Henry's Notebook mediawiki https://wiki.henryhu.net/wiki/%E9%A6%96%E9%A1%B5 MediaWiki 1.33.0 first-letter 媒体文件 特殊 讨论 用户 用户讨论 HenryNotebook HenryNotebook讨论 文件 文件讨论 MediaWiki MediaWiki讨论 模板 模板讨论 帮助 帮助讨论 分类 分类讨论 AndWell BBS Gadget Gadget talk Gadget definition Gadget definition talk 首页 0 1 1 2011-09-13T21:01:31Z MediaWiki default 0 wikitext text/x-wiki '''已成功安装MediaWiki。''' 请查阅[http://meta.wikimedia.org/wiki/Help:Contents 用户指南]以获取使用本wiki软件的信息! == 入门 == * [http://www.mediawiki.org/wiki/Manual:Configuration_settings MediaWiki 配置设置列表] * [http://www.mediawiki.org/wiki/Manual:FAQ/zh-hans MediaWiki常见问题] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki发布邮件列表] 104040084f8d799bfc6a7d84915e08288d1e0419 21 1 2011-09-16T03:05:28Z HenryHu 1 wikitext text/x-wiki [[SubsConscious]] == 入门 == * [http://www.mediawiki.org/wiki/Manual:Configuration_settings MediaWiki 配置设置列表] * [http://www.mediawiki.org/wiki/Manual:FAQ/zh-hans MediaWiki常见问题] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki发布邮件列表] 6f6297deadcdb615b0e056d0573902a9297d6126 22 21 2011-09-16T06:39:45Z HenryHu 1 wikitext text/x-wiki [[SubsConscious]] [[刷课机]] == 入门 == * [http://www.mediawiki.org/wiki/Manual:Configuration_settings MediaWiki 配置设置列表] * [http://www.mediawiki.org/wiki/Manual:FAQ/zh-hans MediaWiki常见问题] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki发布邮件列表] 5a5da2b6c0ef863b68b43bcceff3de31259806a7 33 22 2011-09-16T07:07:21Z HenryHu 1 wikitext text/x-wiki [[SubsConscious]] [[:Category:脚本]] == 入门 == * [http://www.mediawiki.org/wiki/Manual:Configuration_settings MediaWiki 配置设置列表] * [http://www.mediawiki.org/wiki/Manual:FAQ/zh-hans MediaWiki常见问题] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki发布邮件列表] 6702dad770ab9ebb54073b6fe8ecb484c0670942 Pkgdb Problems 0 2 2 2011-09-14T04:43:25Z HenryHu 1 以内容“List of problems in pkgdb, which makes it slow: * In auto mode, the fix_cycles() still checks for cycles. However, it only outputs the results and does not fix them. S...”创建新页面 wikitext text/x-wiki List of problems in pkgdb, which makes it slow: * In auto mode, the fix_cycles() still checks for cycles. However, it only outputs the results and does not fix them. Since the auto mode is usually called by portupgrade, this wastes time. Solution: skip this stage in auto mode. 44883287dfa9ef51ec2a7e3dcb9cc918f32f1ea9 3 2 2011-09-14T04:58:35Z HenryHu 1 wikitext text/x-wiki List of problems in pkgdb, which make it slow: * In auto mode, the fix_cycles() still checks for cycles. However, it only outputs the results and does not fix them. Since the auto mode is usually called by portupgrade, this wastes time. Solution: skip this stage in auto mode. 50248870c3e540b52315c4c2334fd598304e7fb7 4 3 2011-09-14T04:59:03Z HenryHu 1 wikitext text/x-wiki List of problems in pkgdb, which make it slow: * In auto mode, the fix_cycles() still checks for cycles. However, it only outputs the results and does not fix them. Since the auto mode is usually called by portupgrade, this wastes time. Solution: skip this stage in auto mode. Effect: reduced time from 1:44 to 0:30 057e875ac557dc5b76ca22adb6c61e0b19042135 5 4 2011-09-14T05:01:13Z HenryHu 1 wikitext text/x-wiki List of problems in pkgdb, which make it slow: * In auto mode, the fix_cycles() still checks for cycles. However, it only outputs the results and does not fix them. Since the auto mode is usually called by portupgrade, this wastes time. Solution: skip this stage in auto mode. Effect: reduced time from 1:44 to 0:30 * Even there is no changes, we still regenerate +REQUIRED_BY Solution: if not changed, do not regenerate Effect: reduced time from 0:30 to 0:23 92f7888a6595b1c0c9d7e6a58a56b65419f00635 SubsConscious 0 3 6 2011-09-16T00:56:34Z HenryHu 1 以内容“SubsConscious 是哥大边上,Amsterdam Av. 上的一个店,主营subs和salad SubsConscious: great food. great service. www.subsconscious.com === 评价 === * gr...”创建新页面 wikitext text/x-wiki SubsConscious 是哥大边上,Amsterdam Av. 上的一个店,主营subs和salad SubsConscious: great food. great service. www.subsconscious.com === 评价 === * graduate 过来之后吃的第一种,挺好吃的 * lecture 本来我觉得是各种里面最好的,但是有一次有一个很不好吃。不过那个好像是拿错了,因为里面有炸鱼…… * ivy-league 好像不是很好吃…… * double-trouble 挺好吃的 * bar exam Jingyue推荐的,有beef,味道不错 * bronx-10461 刚开始吃感觉不错,不过吃到后来有奇怪的味道。貌似有汉堡里面那种蔬菜。 * twice-as-nice 挺不好吃的…… b884f120311bcd4c4455cd50cb4f4d3937fc7490 刷课机 0 4 7 2011-09-16T02:09:52Z HenryHu 1 以内容“刷课机,一般指通过模拟用户操作,不断选课,从而试图选上某一门课的用于选课的程序。 === 清华刷课机 === === 北大刷课机 ===”创建新页面 wikitext text/x-wiki 刷课机,一般指通过模拟用户操作,不断选课,从而试图选上某一门课的用于选课的程序。 === 清华刷课机 === === 北大刷课机 === f739b694fb47f75d79edc1d4b55b600b721c1b5e 9 7 2011-09-16T02:24:28Z HenryHu 1 /* 清华刷课机 */ wikitext text/x-wiki 刷课机,一般指通过模拟用户操作,不断选课,从而试图选上某一门课的用于选课的程序。 以下列出了一些我写的刷课机…… === 清华刷课机 === 链接:[文件:coursel.py] 其实写刷课机也是个学习python的过程…… === 北大刷课机 === ec288707862a0aadb9e93813b33fb746561cfba9 10 9 2011-09-16T02:25:22Z HenryHu 1 /* 清华刷课机 */ wikitext text/x-wiki 刷课机,一般指通过模拟用户操作,不断选课,从而试图选上某一门课的用于选课的程序。 以下列出了一些我写的刷课机…… === 清华刷课机 === 链接:[[文件:coursel.py]] 其实写刷课机也是个学习python的过程…… === 北大刷课机 === 38f04388122783f9097b2f832eeb0cedbf0bde25 11 10 2011-09-16T02:25:49Z HenryHu 1 /* 清华刷课机 */ wikitext text/x-wiki 刷课机,一般指通过模拟用户操作,不断选课,从而试图选上某一门课的用于选课的程序。 以下列出了一些我写的刷课机…… === 清华刷课机 === 链接:[[文件:coursel.py|coursel.py]] 其实写刷课机也是个学习python的过程…… === 北大刷课机 === f26b578abb27aaf79814fc7a73690b2b73eae0ab 13 11 2011-09-16T02:31:27Z HenryHu 1 /* 北大刷课机 */ wikitext text/x-wiki 刷课机,一般指通过模拟用户操作,不断选课,从而试图选上某一门课的用于选课的程序。 以下列出了一些我写的刷课机…… === 清华刷课机 === 链接:[[文件:coursel.py|coursel.py]] 其实写刷课机也是个学习python的过程…… === 北大刷课机 === 链接:[[文件:coursel_pku.py]] 链接:[[文件:pointrmv.cpp]] 链接:[[文件:c_pku.tar.gz]] 在清华的基础上改的,结构基本相同…… 另外,这里引用了一个文件,pointrmv。北大的验证码太弱智了,所以自己搞了个简单的程序用来识别验证码…… 这个验证码识别工具还用到了一些标准图像,从北大验证码里截的…… 这些在那个压缩包里。其实那个包里也有另外两个文件…… 08dc2b228c341eece8028e4625fbfbdfa00cf170 14 13 2011-09-16T02:31:38Z HenryHu 1 /* 北大刷课机 */ wikitext text/x-wiki 刷课机,一般指通过模拟用户操作,不断选课,从而试图选上某一门课的用于选课的程序。 以下列出了一些我写的刷课机…… === 清华刷课机 === 链接:[[文件:coursel.py|coursel.py]] 其实写刷课机也是个学习python的过程…… === 北大刷课机 === 链接:[[文件:coursel_pku.py]] 链接:[[文件:pointrmv.cpp]] 链接:[[文件:c_pku.tar.gz]] 在清华的基础上改的,结构基本相同…… 另外,这里引用了一个文件,pointrmv。北大的验证码太弱智了,所以自己搞了个简单的程序用来识别验证码…… 这个验证码识别工具还用到了一些标准图像,从北大验证码里截的…… 这些在那个压缩包里。其实那个包里也有另外两个文件…… 9feace8cd0969ed69dd7ba353c020935d29da4ba 17 14 2011-09-16T02:33:06Z HenryHu 1 /* 北大刷课机 */ wikitext text/x-wiki 刷课机,一般指通过模拟用户操作,不断选课,从而试图选上某一门课的用于选课的程序。 以下列出了一些我写的刷课机…… === 清华刷课机 === 链接:[[文件:coursel.py|coursel.py]] 其实写刷课机也是个学习python的过程…… == 北大刷课机 == 链接:[[文件:coursel_pku.py]] 链接:[[文件:pointrmv.cpp]] 链接:[[文件:c_pku.tar.gz]] 在清华的基础上改的,结构基本相同…… 另外,这里引用了一个文件,pointrmv。北大的验证码太弱智了,所以自己搞了个简单的程序用来识别验证码…… 这个验证码识别工具还用到了一些标准图像,从北大验证码里截的…… 这些在那个压缩包里。其实那个包里也有另外两个文件…… c941d7025c699a857d47b04644faf0b749ac983a 18 17 2011-09-16T02:33:59Z HenryHu 1 /* 清华刷课机 */ wikitext text/x-wiki 刷课机,一般指通过模拟用户操作,不断选课,从而试图选上某一门课的用于选课的程序。 以下列出了一些我写的刷课机…… == 清华刷课机 == 链接:[[文件:coursel.py|coursel.py]] 其实写刷课机也是个学习python的过程…… 清华的验证码比较复杂。为了识别这个验证码,用到了cuneiform。其实gocr的效果也不错。 == 北大刷课机 == 链接:[[文件:coursel_pku.py]] 链接:[[文件:pointrmv.cpp]] 链接:[[文件:c_pku.tar.gz]] 在清华的基础上改的,结构基本相同…… 另外,这里引用了一个文件,pointrmv。北大的验证码太弱智了,所以自己搞了个简单的程序用来识别验证码…… 这个验证码识别工具还用到了一些标准图像,从北大验证码里截的…… 这些在那个压缩包里。其实那个包里也有另外两个文件…… ecdf0a868f9035b9f1cc447618998102c002f9c2 19 18 2011-09-16T02:37:23Z HenryHu 1 /* 北大刷课机 */ wikitext text/x-wiki 刷课机,一般指通过模拟用户操作,不断选课,从而试图选上某一门课的用于选课的程序。 以下列出了一些我写的刷课机…… == 清华刷课机 == 链接:[[文件:coursel.py|coursel.py]] 其实写刷课机也是个学习python的过程…… 清华的验证码比较复杂。为了识别这个验证码,用到了cuneiform。其实gocr的效果也不错。 == 北大刷课机 == 链接:[[文件:coursel_pku.py]] 链接:[[文件:pointrmv.cpp]] 链接:[[文件:c_pku.tar.gz]] 在清华的基础上改的,结构基本相同…… 另外,这里引用了一个文件,pointrmv。北大的验证码太弱智了,所以自己搞了个简单的程序用来识别验证码…… 这个验证码识别工具还用到了一些标准图像,从北大验证码里截的…… 这些在那个压缩包里。其实那个包里也有另外两个文件…… === 验证码识别 === 北大的验证码实在太弱,基本上就加了些噪点,别的没了…… 所以识别程序先去掉那些点,然后匹配图片就完了。 用了libjpeg来载入图片。噪点识别好像就是看看深浅,太久了,忘了…… 反正很弱…… f1faecef0362c3b5fdb7b733ef6a1b0d2126597d 20 19 2011-09-16T02:39:40Z HenryHu 1 /* 验证码识别 */ wikitext text/x-wiki 刷课机,一般指通过模拟用户操作,不断选课,从而试图选上某一门课的用于选课的程序。 以下列出了一些我写的刷课机…… == 清华刷课机 == 链接:[[文件:coursel.py|coursel.py]] 其实写刷课机也是个学习python的过程…… 清华的验证码比较复杂。为了识别这个验证码,用到了cuneiform。其实gocr的效果也不错。 == 北大刷课机 == 链接:[[文件:coursel_pku.py]] 链接:[[文件:pointrmv.cpp]] 链接:[[文件:c_pku.tar.gz]] 在清华的基础上改的,结构基本相同…… 另外,这里引用了一个文件,pointrmv。北大的验证码太弱智了,所以自己搞了个简单的程序用来识别验证码…… 这个验证码识别工具还用到了一些标准图像,从北大验证码里截的…… 这些在那个压缩包里。其实那个包里也有另外两个文件…… === 验证码识别 === 北大的验证码实在太弱,基本上就加了些噪点,别的没了…… 所以识别程序先去掉那些点,然后匹配图片就完了。 用了libjpeg来载入图片。噪点识别好像就是看看深浅,太久了,忘了…… 反正很弱…… === 某人被抓事件 === 好像某人拿我的刷课机在北大刷课的时候被抓了。然后他们那边的老师还让他交出源代码啥的。 但是其实不是他自己刷,而是我在清华访问北大网络刷课。因此,他也没有源代码。后来他联系我,说老师只要他交出源代码就不追究了。 其实这个刷课机也没啥技术含量对吧…… 所以我记得我就给他了。 后来就没有消息了,北大的系统好像还是很烂。 1b0d8c5b187e7331bb5034a8a6f4f9589eb8d878 23 20 2011-09-16T06:41:24Z HenryHu 1 wikitext text/x-wiki [[Category:脚本|script]] 刷课机,一般指通过模拟用户操作,不断选课,从而试图选上某一门课的用于选课的程序。 以下列出了一些我写的刷课机…… == 清华刷课机 == 链接:[[文件:coursel.py|coursel.py]] 其实写刷课机也是个学习python的过程…… 清华的验证码比较复杂。为了识别这个验证码,用到了cuneiform。其实gocr的效果也不错。 == 北大刷课机 == 链接:[[文件:coursel_pku.py]] 链接:[[文件:pointrmv.cpp]] 链接:[[文件:c_pku.tar.gz]] 在清华的基础上改的,结构基本相同…… 另外,这里引用了一个文件,pointrmv。北大的验证码太弱智了,所以自己搞了个简单的程序用来识别验证码…… 这个验证码识别工具还用到了一些标准图像,从北大验证码里截的…… 这些在那个压缩包里。其实那个包里也有另外两个文件…… === 验证码识别 === 北大的验证码实在太弱,基本上就加了些噪点,别的没了…… 所以识别程序先去掉那些点,然后匹配图片就完了。 用了libjpeg来载入图片。噪点识别好像就是看看深浅,太久了,忘了…… 反正很弱…… === 某人被抓事件 === 好像某人拿我的刷课机在北大刷课的时候被抓了。然后他们那边的老师还让他交出源代码啥的。 但是其实不是他自己刷,而是我在清华访问北大网络刷课。因此,他也没有源代码。后来他联系我,说老师只要他交出源代码就不追究了。 其实这个刷课机也没啥技术含量对吧…… 所以我记得我就给他了。 后来就没有消息了,北大的系统好像还是很烂。 5db8332d68cc794f5d5ff1d8afca384ba2193b7c 24 23 2011-09-16T06:41:45Z HenryHu 1 wikitext text/x-wiki [[Category:脚本|coursel]] 刷课机,一般指通过模拟用户操作,不断选课,从而试图选上某一门课的用于选课的程序。 以下列出了一些我写的刷课机…… == 清华刷课机 == 链接:[[文件:coursel.py|coursel.py]] 其实写刷课机也是个学习python的过程…… 清华的验证码比较复杂。为了识别这个验证码,用到了cuneiform。其实gocr的效果也不错。 == 北大刷课机 == 链接:[[文件:coursel_pku.py]] 链接:[[文件:pointrmv.cpp]] 链接:[[文件:c_pku.tar.gz]] 在清华的基础上改的,结构基本相同…… 另外,这里引用了一个文件,pointrmv。北大的验证码太弱智了,所以自己搞了个简单的程序用来识别验证码…… 这个验证码识别工具还用到了一些标准图像,从北大验证码里截的…… 这些在那个压缩包里。其实那个包里也有另外两个文件…… === 验证码识别 === 北大的验证码实在太弱,基本上就加了些噪点,别的没了…… 所以识别程序先去掉那些点,然后匹配图片就完了。 用了libjpeg来载入图片。噪点识别好像就是看看深浅,太久了,忘了…… 反正很弱…… === 某人被抓事件 === 好像某人拿我的刷课机在北大刷课的时候被抓了。然后他们那边的老师还让他交出源代码啥的。 但是其实不是他自己刷,而是我在清华访问北大网络刷课。因此,他也没有源代码。后来他联系我,说老师只要他交出源代码就不追究了。 其实这个刷课机也没啥技术含量对吧…… 所以我记得我就给他了。 后来就没有消息了,北大的系统好像还是很烂。 580824a92c7147501fe573f405f3415227626204 文件:Coursel.py 6 5 8 2011-09-16T02:23:02Z HenryHu 1 刷课机基础版本-清华用 wikitext text/x-wiki 刷课机基础版本-清华用 f6e30c3d8ca7a6873f50bb69997ca89a624c1d93 文件:Coursel pku.py 6 6 12 2011-09-16T02:26:27Z HenryHu 1 刷课机-北大版 wikitext text/x-wiki 刷课机-北大版 7d73f0c688ec51f314e8c03a82f37cdb1399b33e 文件:Pointrmv.cpp 6 7 15 2011-09-16T02:32:08Z HenryHu 1 刷课机里的识别程序 wikitext text/x-wiki 刷课机里的识别程序 110f4328e44c2ad7474d082b891a1896ac2ddefa 文件:C pku.tar.gz 6 8 16 2011-09-16T02:32:48Z HenryHu 1 完整的北大刷课机包…… wikitext text/x-wiki 完整的北大刷课机包…… 951f8f1f0cba7686e200347c78c1accddcf104eb 分类:脚本 14 9 25 2011-09-16T06:42:17Z HenryHu 1 以内容“这个分类下有各种脚本……”创建新页面 wikitext text/x-wiki 这个分类下有各种脚本…… e91039aec5b5d464e118188d916a483b28e49236 Subwrap 0 10 26 2011-09-16T06:56:05Z HenryHu 1 以内容“subwrap 是我写的一个小脚本,用来自动查找某视频对应的脚本,然后调用播放器播放。 因为我非常喜欢mplayer,所以目前只调用m...”创建新页面 wikitext text/x-wiki subwrap 是我写的一个小脚本,用来自动查找某视频对应的脚本,然后调用播放器播放。 因为我非常喜欢mplayer,所以目前只调用mplayer,因为我放啥都是用这个…… 下载: [[文件:subwrap.pl]] [code] #!/usr/bin/perl sub playfile { my($file, $sub, $encoding, $args) = @_; if ($encoding eq "") { system("mplayer \"$file\" -sub \"$sub\" -utf8 $args"); } else { # system("iconv -f $encoding -c \"$sub\" | mplayer \"$file\" -sub - -utf8 $args"); system("iconv -f $encoding -c \"$sub\" > /tmp/subtitle.sub"); system("mplayer \"$file\" -ass -sub /tmp/subtitle.sub -utf8 $args"); system("rm -f /tmp/subtitle.sub"); } } @exts = ('srt','ssa','ass'); @langs = ('en','Eng','chs','Chs','cn','sc','SC','uni_gb','gb','GB','cht','tc','TC','uni_big5','neta'); if ($#ARGV == -1) { print "Usage: subwrap <filename>\n"; exit 1; } $fname = $ARGV[0]; $argstr = ""; for ($i = 1; $i <= $#ARGV; $i = $i + 1) { $argstr = $argstr . $ARGV[$i] . " "; } if (!(-e $fname)) { print "Cannot find specified file.\n"; exit 2; } if (!($fname =~ m/(.*)\.(.*)/)) { print "Cannot find . in filename.\n"; exit 1; } for ($way = 0; $way < 2; $way++) { if ($way == 0) { $fname =~ m/(.*)\.(.*)/; $basename = $1; } else { $fname =~ m/(.*)\[.*\]\.(.*)/; $basename = $1; } # First let's try only extensions foreach $i (@exts) { $subname = $basename . "." . $i; if (-e $subname) { goto FOUND; } } # Now let's try extensions with languages foreach $i (@langs) { foreach $j (@exts) { $subname = $basename . "." . $i . "." . $j; if (-e $subname) { goto FOUND; } } } } # We failed! print "Cannot found subtitles in (@exts) or (@langs) . (@exts).\n"; exit 2; FOUND: $filetype = `file "$subname"`; print "Found sub file: $subname\n"; if ($filetype =~ m/ISO-8859/ or $filetype =~ m/extended-ASCII/) { # GBK file print "Converting from GBK encoding\n"; playfile($fname, $subname, "gbk", $argstr); } elsif ($filetype =~ m/UTF-16/) { # UTF-16 file if ($filetype =~ m/Little-endian/) { # UTF-16 Little Endian print "Converting from UTF-16LE encoding\n"; playfile($fname, $subname, "utf-16le", $argstr); } else { # UTF-16 Big Endian print "Converting from UTF-16BE encoding\n"; playfile($fname, $subname, "utf-16be", $argstr); } } else { playfile($fname, $subname, "", $argstr); } [/code] 3958891a4ebe2e66496b9eb3df0992d639b111ec 27 26 2011-09-16T06:59:43Z HenryHu 1 wikitext text/x-wiki subwrap 是我写的一个小脚本,用来自动查找某视频对应的脚本,然后调用播放器播放。 因为我非常喜欢mplayer,所以目前只调用mplayer,因为我放啥都是用这个…… 下载: [[文件:subwrap.pl]] <syntaxhighlight lang="perl"> #!/usr/bin/perl sub playfile { my($file, $sub, $encoding, $args) = @_; if ($encoding eq "") { system("mplayer \"$file\" -sub \"$sub\" -utf8 $args"); } else { # system("iconv -f $encoding -c \"$sub\" | mplayer \"$file\" -sub - -utf8 $args"); system("iconv -f $encoding -c \"$sub\" > /tmp/subtitle.sub"); system("mplayer \"$file\" -ass -sub /tmp/subtitle.sub -utf8 $args"); system("rm -f /tmp/subtitle.sub"); } } @exts = ('srt','ssa','ass'); @langs = ('en','Eng','chs','Chs','cn','sc','SC','uni_gb','gb','GB','cht','tc','TC','uni_big5','neta'); if ($#ARGV == -1) { print "Usage: subwrap <filename>\n"; exit 1; } $fname = $ARGV[0]; $argstr = ""; for ($i = 1; $i <= $#ARGV; $i = $i + 1) { $argstr = $argstr . $ARGV[$i] . " "; } if (!(-e $fname)) { print "Cannot find specified file.\n"; exit 2; } if (!($fname =~ m/(.*)\.(.*)/)) { print "Cannot find . in filename.\n"; exit 1; } for ($way = 0; $way < 2; $way++) { if ($way == 0) { $fname =~ m/(.*)\.(.*)/; $basename = $1; } else { $fname =~ m/(.*)\[.*\]\.(.*)/; $basename = $1; } # First let's try only extensions foreach $i (@exts) { $subname = $basename . "." . $i; if (-e $subname) { goto FOUND; } } # Now let's try extensions with languages foreach $i (@langs) { foreach $j (@exts) { $subname = $basename . "." . $i . "." . $j; if (-e $subname) { goto FOUND; } } } } # We failed! print "Cannot found subtitles in (@exts) or (@langs) . (@exts).\n"; exit 2; FOUND: $filetype = `file "$subname"`; print "Found sub file: $subname\n"; if ($filetype =~ m/ISO-8859/ or $filetype =~ m/extended-ASCII/) { # GBK file print "Converting from GBK encoding\n"; playfile($fname, $subname, "gbk", $argstr); } elsif ($filetype =~ m/UTF-16/) { # UTF-16 file if ($filetype =~ m/Little-endian/) { # UTF-16 Little Endian print "Converting from UTF-16LE encoding\n"; playfile($fname, $subname, "utf-16le", $argstr); } else { # UTF-16 Big Endian print "Converting from UTF-16BE encoding\n"; playfile($fname, $subname, "utf-16be", $argstr); } } else { playfile($fname, $subname, "", $argstr); } </syntaxhighlight> cf6ab3da8e543764cb061cd0757b2d09ef903554 28 27 2011-09-16T07:00:18Z HenryHu 1 wikitext text/x-wiki subwrap 是我写的一个小脚本,用来自动查找某视频对应的脚本,然后调用播放器播放。 因为我非常喜欢mplayer,所以目前只调用mplayer,因为我放啥都是用这个…… 因为我用的FreeBSD,所以这个脚本我只在BSD下试过。别的系统下面,file的返回结果可能不一样,要做相应修改…… 下载: [[文件:subwrap.pl]] <syntaxhighlight lang="perl"> #!/usr/bin/perl sub playfile { my($file, $sub, $encoding, $args) = @_; if ($encoding eq "") { system("mplayer \"$file\" -sub \"$sub\" -utf8 $args"); } else { # system("iconv -f $encoding -c \"$sub\" | mplayer \"$file\" -sub - -utf8 $args"); system("iconv -f $encoding -c \"$sub\" > /tmp/subtitle.sub"); system("mplayer \"$file\" -ass -sub /tmp/subtitle.sub -utf8 $args"); system("rm -f /tmp/subtitle.sub"); } } @exts = ('srt','ssa','ass'); @langs = ('en','Eng','chs','Chs','cn','sc','SC','uni_gb','gb','GB','cht','tc','TC','uni_big5','neta'); if ($#ARGV == -1) { print "Usage: subwrap <filename>\n"; exit 1; } $fname = $ARGV[0]; $argstr = ""; for ($i = 1; $i <= $#ARGV; $i = $i + 1) { $argstr = $argstr . $ARGV[$i] . " "; } if (!(-e $fname)) { print "Cannot find specified file.\n"; exit 2; } if (!($fname =~ m/(.*)\.(.*)/)) { print "Cannot find . in filename.\n"; exit 1; } for ($way = 0; $way < 2; $way++) { if ($way == 0) { $fname =~ m/(.*)\.(.*)/; $basename = $1; } else { $fname =~ m/(.*)\[.*\]\.(.*)/; $basename = $1; } # First let's try only extensions foreach $i (@exts) { $subname = $basename . "." . $i; if (-e $subname) { goto FOUND; } } # Now let's try extensions with languages foreach $i (@langs) { foreach $j (@exts) { $subname = $basename . "." . $i . "." . $j; if (-e $subname) { goto FOUND; } } } } # We failed! print "Cannot found subtitles in (@exts) or (@langs) . (@exts).\n"; exit 2; FOUND: $filetype = `file "$subname"`; print "Found sub file: $subname\n"; if ($filetype =~ m/ISO-8859/ or $filetype =~ m/extended-ASCII/) { # GBK file print "Converting from GBK encoding\n"; playfile($fname, $subname, "gbk", $argstr); } elsif ($filetype =~ m/UTF-16/) { # UTF-16 file if ($filetype =~ m/Little-endian/) { # UTF-16 Little Endian print "Converting from UTF-16LE encoding\n"; playfile($fname, $subname, "utf-16le", $argstr); } else { # UTF-16 Big Endian print "Converting from UTF-16BE encoding\n"; playfile($fname, $subname, "utf-16be", $argstr); } } else { playfile($fname, $subname, "", $argstr); } </syntaxhighlight> 7596fd6261ae729e692353eb2b40ecaf6bc389c2 30 28 2011-09-16T07:01:22Z HenryHu 1 wikitext text/x-wiki [[Category:脚本|subwrap]] subwrap 是我写的一个小脚本,用来自动查找某视频对应的脚本,然后调用播放器播放。 因为我非常喜欢mplayer,所以目前只调用mplayer,因为我放啥都是用这个…… 因为我用的FreeBSD,所以这个脚本我只在BSD下试过。别的系统下面,file的返回结果可能不一样,要做相应修改…… 下载: [[文件:subwrap.pl]] <syntaxhighlight lang="perl"> #!/usr/bin/perl sub playfile { my($file, $sub, $encoding, $args) = @_; if ($encoding eq "") { system("mplayer \"$file\" -sub \"$sub\" -utf8 $args"); } else { # system("iconv -f $encoding -c \"$sub\" | mplayer \"$file\" -sub - -utf8 $args"); system("iconv -f $encoding -c \"$sub\" > /tmp/subtitle.sub"); system("mplayer \"$file\" -ass -sub /tmp/subtitle.sub -utf8 $args"); system("rm -f /tmp/subtitle.sub"); } } @exts = ('srt','ssa','ass'); @langs = ('en','Eng','chs','Chs','cn','sc','SC','uni_gb','gb','GB','cht','tc','TC','uni_big5','neta'); if ($#ARGV == -1) { print "Usage: subwrap <filename>\n"; exit 1; } $fname = $ARGV[0]; $argstr = ""; for ($i = 1; $i <= $#ARGV; $i = $i + 1) { $argstr = $argstr . $ARGV[$i] . " "; } if (!(-e $fname)) { print "Cannot find specified file.\n"; exit 2; } if (!($fname =~ m/(.*)\.(.*)/)) { print "Cannot find . in filename.\n"; exit 1; } for ($way = 0; $way < 2; $way++) { if ($way == 0) { $fname =~ m/(.*)\.(.*)/; $basename = $1; } else { $fname =~ m/(.*)\[.*\]\.(.*)/; $basename = $1; } # First let's try only extensions foreach $i (@exts) { $subname = $basename . "." . $i; if (-e $subname) { goto FOUND; } } # Now let's try extensions with languages foreach $i (@langs) { foreach $j (@exts) { $subname = $basename . "." . $i . "." . $j; if (-e $subname) { goto FOUND; } } } } # We failed! print "Cannot found subtitles in (@exts) or (@langs) . (@exts).\n"; exit 2; FOUND: $filetype = `file "$subname"`; print "Found sub file: $subname\n"; if ($filetype =~ m/ISO-8859/ or $filetype =~ m/extended-ASCII/) { # GBK file print "Converting from GBK encoding\n"; playfile($fname, $subname, "gbk", $argstr); } elsif ($filetype =~ m/UTF-16/) { # UTF-16 file if ($filetype =~ m/Little-endian/) { # UTF-16 Little Endian print "Converting from UTF-16LE encoding\n"; playfile($fname, $subname, "utf-16le", $argstr); } else { # UTF-16 Big Endian print "Converting from UTF-16BE encoding\n"; playfile($fname, $subname, "utf-16be", $argstr); } } else { playfile($fname, $subname, "", $argstr); } </syntaxhighlight> 6aeb83772e7d2d36b2cb9105d3140df76229f3c3 文件:Subwrap.pl 6 11 29 2011-09-16T07:00:42Z HenryHu 1 自动查找字幕的脚本 wikitext text/x-wiki 自动查找字幕的脚本 6db705d01074fff216c05f63f87b7951337b49c3 MediaWiki:Sidebar 8 12 31 2011-09-16T07:04:11Z HenryHu 1 以内容“* navigation ** mainpage|mainpage-description ** portal-url|portal ** currentevents-url|currentevents ** recentchanges-url|recentchanges <!-- ** randompage-url|randompa...”创建新页面 wikitext text/x-wiki * navigation ** mainpage|mainpage-description ** portal-url|portal ** currentevents-url|currentevents ** recentchanges-url|recentchanges <!-- ** randompage-url|randompage --> ** helppage|help * SEARCH * TOOLBOX * LANGUAGES 5af4f6a7033508b4772668afcef542b6c3e1b705 32 31 2011-09-16T07:05:09Z HenryHu 1 wikitext text/x-wiki * navigation ** mainpage|mainpage-description ** portal-url|portal ** currentevents-url|currentevents ** recentchanges-url|recentchanges <!-- ** randompage-url|randompage --> ** helppage|help ** http://www.henryhu.net|Henry's Home * SEARCH * TOOLBOX * LANGUAGES 6243bdc3080155bbeb26223fbd2ab86a16e67ff3 Mountiso 0 13 34 2011-09-16T07:13:18Z HenryHu 1 以内容“简单的给FreeBSD用的脚本,用来把一个ISO文件挂到/cdrom下面。 <source lang="perl"> #!/usr/bin/perl $node = `mdconfig -a -t vnode -f "@ARGV[0]"`; cho...”创建新页面 wikitext text/x-wiki 简单的给FreeBSD用的脚本,用来把一个ISO文件挂到/cdrom下面。 <source lang="perl"> #!/usr/bin/perl $node = `mdconfig -a -t vnode -f "@ARGV[0]"`; chop($node); if ($node !~ /md\d+/) { die "mdconfig failed."; } print "Mounting /dev/$node to /cdrom\n"; $ret = system("mount_cd9660 /dev/$node /cdrom"); if ($ret != 0) { print "mount failed\n"; system("mdconfig -d -u $node"); } $ret </source> ab32a3e646141f4aa2f0e188f45300f3a9535df1 35 34 2011-09-16T07:13:35Z HenryHu 1 wikitext text/x-wiki [[Category:脚本|mountiso]] 简单的给FreeBSD用的脚本,用来把一个ISO文件挂到/cdrom下面。 <source lang="perl"> #!/usr/bin/perl $node = `mdconfig -a -t vnode -f "@ARGV[0]"`; chop($node); if ($node !~ /md\d+/) { die "mdconfig failed."; } print "Mounting /dev/$node to /cdrom\n"; $ret = system("mount_cd9660 /dev/$node /cdrom"); if ($ret != 0) { print "mount failed\n"; system("mdconfig -d -u $node"); } $ret </source> 4f81a62cc424202a6140bb13af90f10a5926aab6 Wlanauth 0 14 36 2011-09-16T07:15:09Z HenryHu 1 以内容“BSD下的利用wpa_supplicant来自动找到并且连上加密无线网的脚本。 <source lang="sh"> #!/bin/sh if [ "`ifconfig | grep wlan0 | grep -v grep`" = "" ];...”创建新页面 wikitext text/x-wiki BSD下的利用wpa_supplicant来自动找到并且连上加密无线网的脚本。 <source lang="sh"> #!/bin/sh if [ "`ifconfig | grep wlan0 | grep -v grep`" = "" ]; then echo "Loading driver and creating device..." kldload if_wpi ifconfig wlan0 create wlandev wpi0 ifconfig wlan0 up ifconfig wlan0 bmiss 255 else echo "Reloading wlan driver..." ifconfig wlan0 down up fi sleep 1 count=0 wpa_supplicant -s -B -iwlan0 -c/home/henryhu/conf/wpa_supplicant.conf while true; do echo "No. $count result: "; ifconfig wlan0; if [ "`ifconfig wlan0 | grep associated | grep -v grep`" != "" ]; then echo "Associated. Getting IP..." route delete default; dhclient wlan0; break; fi; if [ "$count" = "10" ]; then count=0 echo "Reloading wlan driver..." ifconfig wlan0 down up pkill wpa_supplicant wpa_supplicant -s -B -iwlan0 -c/home/henryhu/conf/wpa_supplicant.conf fi sleep 2; count=`expr $count + 1` done </source> 26a1c9100810315e77e8ab82ffc97ced1f3ab290 37 36 2011-09-16T07:15:28Z HenryHu 1 wikitext text/x-wiki [[Category:脚本]] BSD下的利用wpa_supplicant来自动找到并且连上加密无线网的脚本。 <source lang="bash"> #!/bin/sh if [ "`ifconfig | grep wlan0 | grep -v grep`" = "" ]; then echo "Loading driver and creating device..." kldload if_wpi ifconfig wlan0 create wlandev wpi0 ifconfig wlan0 up ifconfig wlan0 bmiss 255 else echo "Reloading wlan driver..." ifconfig wlan0 down up fi sleep 1 count=0 wpa_supplicant -s -B -iwlan0 -c/home/henryhu/conf/wpa_supplicant.conf while true; do echo "No. $count result: "; ifconfig wlan0; if [ "`ifconfig wlan0 | grep associated | grep -v grep`" != "" ]; then echo "Associated. Getting IP..." route delete default; dhclient wlan0; break; fi; if [ "$count" = "10" ]; then count=0 echo "Reloading wlan driver..." ifconfig wlan0 down up pkill wpa_supplicant wpa_supplicant -s -B -iwlan0 -c/home/henryhu/conf/wpa_supplicant.conf fi sleep 2; count=`expr $count + 1` done </source> 5ac084ef6741addd2b8a8aaa54804037da024acb Wlangate 0 15 38 2011-09-16T07:18:14Z HenryHu 1 以内容“[[Category:脚本]] 一个和[[wlanauth]]同源的脚本,连上无线网之后,将当前有线连接在无线网上共享的脚本。 <source lang="bash"> #!/bin/...”创建新页面 wikitext text/x-wiki [[Category:脚本]] 一个和[[wlanauth]]同源的脚本,连上无线网之后,将当前有线连接在无线网上共享的脚本。 <source lang="bash"> #!/bin/sh if [ "`ifconfig | grep wlan0 | grep -v grep`" = "" ]; then echo "Loading driver and creating device..." kldload if_wpi ifconfig wlan0 create wlandev wpi0 ifconfig wlan0 up ifconfig wlan0 bmiss 255 fi if [ "`ifconfig wlan0 | grep status | grep running`" = "" ]; then wpa_supplicant -B -iwlan0 -c/home/henryhu/conf/wpa_supplicant.conf fi echo -n "Waiting to be associated " MY_ID=`wpa_cli list | grep henryhu | cut -f 1` while true; do echo -n .; if [ "`ifconfig wlan0 | grep -E '(associated|running)' | grep -v grep`" != "" ]; then SID_NAME=`ifconfig wlan0 | grep ssid | cut -f 2 -d \ ` echo "Associated with $SID_NAME." if [ "$SID_NAME" = "henryhu" ]; then break; else echo "Associated with other's wlan, reassociate"; wpa_cli select_network $MY_ID wpa_cli reassoc fi fi; sleep 1; done echo "Setting IP to 192.168.137.1 ..." ifconfig wlan0 192.168.137.1 echo "Enable forwarding..." sysctl net.inet.ip.forwarding=1 echo "Modify firewall..." #ipfw add 1050 divert 8668 ip4 from any to any via ue0 kldload ipfw_nat pkill fwder /home/henryhu/src/fwder & ipfw nat 1 config if ue0 log same_ports reset ipfw add 1030 allow tcp from me to any via wlan0 ipfw add 1040 allow tcp from any to me via wlan0 ipfw add 1050 nat 1 ip4 from any to any via ue0 ipfw add 1060 nat 1 ip4 from any to any via wlan0 ipfw add 1070 fwd 192.168.137.1,3128 tcp from any to any dst-port 80 via wlan0 ipfw add 1080 fwd 192.168.137.1,8443 tcp from any to any dst-port 443 via wlan0 ipfw add 1090 allow ip from not me to not me echo "Starting DHCP server..." /usr/local/etc/rc.d/isc-dhcpd onestart echo "Done!" </source> 6d0ae3537fcff996432d4d2ce9b1fc401c89f01c 39 38 2011-09-16T07:20:12Z HenryHu 1 wikitext text/x-wiki [[Category:脚本]] 一个和[[wlanauth]]同源的脚本,连上无线网之后,将当前有线连接在无线网上共享的脚本。 其中的[[fwder]]是一个程序,非常简单,主要是用来在HTTP proxy支持CONNECT的情况下,实现透明HTTPS代理的。用这个搞的HTTPS代理连证书都没问题…… <source lang="bash"> #!/bin/sh if [ "`ifconfig | grep wlan0 | grep -v grep`" = "" ]; then echo "Loading driver and creating device..." kldload if_wpi ifconfig wlan0 create wlandev wpi0 ifconfig wlan0 up ifconfig wlan0 bmiss 255 fi if [ "`ifconfig wlan0 | grep status | grep running`" = "" ]; then wpa_supplicant -B -iwlan0 -c/home/henryhu/conf/wpa_supplicant.conf fi echo -n "Waiting to be associated " MY_ID=`wpa_cli list | grep henryhu | cut -f 1` while true; do echo -n .; if [ "`ifconfig wlan0 | grep -E '(associated|running)' | grep -v grep`" != "" ]; then SID_NAME=`ifconfig wlan0 | grep ssid | cut -f 2 -d \ ` echo "Associated with $SID_NAME." if [ "$SID_NAME" = "henryhu" ]; then break; else echo "Associated with other's wlan, reassociate"; wpa_cli select_network $MY_ID wpa_cli reassoc fi fi; sleep 1; done echo "Setting IP to 192.168.137.1 ..." ifconfig wlan0 192.168.137.1 echo "Enable forwarding..." sysctl net.inet.ip.forwarding=1 echo "Modify firewall..." #ipfw add 1050 divert 8668 ip4 from any to any via ue0 kldload ipfw_nat pkill fwder /home/henryhu/src/fwder & ipfw nat 1 config if ue0 log same_ports reset ipfw add 1030 allow tcp from me to any via wlan0 ipfw add 1040 allow tcp from any to me via wlan0 ipfw add 1050 nat 1 ip4 from any to any via ue0 ipfw add 1060 nat 1 ip4 from any to any via wlan0 ipfw add 1070 fwd 192.168.137.1,3128 tcp from any to any dst-port 80 via wlan0 ipfw add 1080 fwd 192.168.137.1,8443 tcp from any to any dst-port 443 via wlan0 ipfw add 1090 allow ip from not me to not me echo "Starting DHCP server..." /usr/local/etc/rc.d/isc-dhcpd onestart echo "Done!" </source> 6b597ba19f4704fc7b915bb01fd215a7b262ae94 Fwder 0 16 40 2011-09-16T07:21:52Z HenryHu 1 以内容“[[Category:程序]] fwder的作用主要是通过一个HTTP proxy,转发HTTPS的连接。它主要是用在透明代理上的。 <source lang="c"> #include <sys/soc...”创建新页面 wikitext text/x-wiki [[Category:程序]] fwder的作用主要是通过一个HTTP proxy,转发HTTPS的连接。它主要是用在透明代理上的。 <source lang="c"> #include <sys/socket.h> #include <netdb.h> #include <sys/types.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <signal.h> char proxy_addr[] = "127.0.0.1"; char proxy_port[] = "8120"; int main() { sigignore(SIGCHLD); struct addrinfo *ai; struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; int ret = getaddrinfo("::", "8443", &hints, &ai); if (ret) { fprintf(stderr, "failed to getaddrinfo: %s\n", gai_strerror(ret)); return 1; } int s = -1; while (ai) { s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (s < 0) { ai = ai->ai_next; continue; } int val = 1; setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); ret = bind(s, ai->ai_addr, ai->ai_addrlen); if (ret < 0) { close(s); s = -1; ai = ai->ai_next; continue; } break; } if (s < 0) { perror("failed to create and bind sock: "); return 1; } ret = listen(s, 10); if (ret < 0) { perror("failed to listen: "); return 1; } while (1) { struct sockaddr_storage cliaddr, myaddr; socklen_t cl = sizeof(cliaddr); socklen_t ml = sizeof(myaddr); int client = accept(s, (struct sockaddr *)&cliaddr, &cl); if (client < 0) { if (errno != ECONNABORTED) break; } char host[256]; char serv[256]; getnameinfo((struct sockaddr *)&cliaddr, cl, host, sizeof(host), serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV); char myhost[256], myserv[256]; getsockname(client, (struct sockaddr *)&myaddr, &ml); getnameinfo((struct sockaddr *)&myaddr, ml, myhost, sizeof(myhost), myserv, sizeof(myserv), NI_NUMERICHOST | NI_NUMERICSERV); pid_t pid = fork(); if (pid == 0) { // close(stdout); // close(stderr); struct addrinfo newhint, *res; memset(&newhint, 0, sizeof(newhint)); newhint.ai_family = AF_UNSPEC; newhint.ai_socktype = SOCK_STREAM; newhint.ai_flags = AI_NUMERICHOST; ret = getaddrinfo(proxy_addr, proxy_port, &hints, &res); if (ret) { // fprintf(stderr, "[%d] failed to getaddrinfo: %s\n", getpid(), gai_strerror(ret)); return 1; } if (strncmp(myhost, "::ffff:", 7) != 0) { return 1; } int xs = -1; while (res) { xs = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (xs < 0) { res = res->ai_next; continue; } int val = 1; setsockopt(xs, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); break; } if (s < 0) { // perror("failed to create sock: "); return 1; } ret = connect(xs, res->ai_addr, res->ai_addrlen); if (ret < 0) { // perror("failed to connect: "); return 1; } char *target = myhost + 7; char req[1500]; char reply[1500]; char *ptr = reply; if (strcmp(target, "78.16.49.15") == 0) { target = "199.59.148.87"; } snprintf(req, sizeof(req), "CONNECT %s:%s HTTP/1.1\r\n\r\n", target, myserv); int linelen = 0; write(xs, req, strlen(req)); int status = 0; while (1) { char c; ret = read(xs, &c, 1); if (ret <= 0) break; if (c == '\r') { read(xs, &c, 1); if (c != '\n') { } if (linelen == 0) { // reply end break; } else { if (strncmp(reply, "HTTP/", 5) == 0) { // reply line if (strstr(reply, " 200") != 0) { // OK status = 1; // printf("STATE OK\n"); } else { status = 0; // printf("STATE ERROR\n"); } } else { // other line // printf("OTHER LINE\n"); } } linelen = 0; // printf("NEW LINE\n"); } else { reply[linelen] = c; linelen++; // printf("%c", c); } } if (status > 0) { char buf[1500]; int max = xs; if (client > xs) max = client; max++; int closed = 0; while (1) { fd_set inout; FD_ZERO(&inout); FD_SET(xs, &inout); FD_SET(client, &inout); /*fprintf(stderr, "ok1 : %d\n", FD_ISSET(client, &inout));*/ /*fprintf(stderr, "ok2 : %d\n", FD_ISSET(xs, &inout));*/ /*printf("before select\n");*/ ret = select(max, &inout, NULL, NULL, NULL); /*printf("after select\n");*/ if (ret == -1) { break; } if (FD_ISSET(xs, &inout)) { /*printf("server data ready\n");*/ int len = read(xs, buf, sizeof(buf)); if (len <= 0) { closed++; shutdown(client, SHUT_WR); } else { /*printf("got server data: %d\n", len);*/ ret = write(client, buf, len); if (ret < len) break; } } if (FD_ISSET(client, &inout)) { /*printf("client data ready\n");*/ int len = read(client, buf, sizeof(buf)); if (len <= 0) { closed++; shutdown(xs, SHUT_WR); } else { /*printf("got data: %d bytes\n", len);*/ ret = write(xs, buf, len); if (ret < len) break; } } if (closed >= 2) break; } } /*printf("EXIT\n");*/ shutdown(xs, SHUT_RDWR); close(xs); shutdown(client, SHUT_RDWR); close(client); return 0; } else { /* printf("new child %d serving %s:%s, at %s:%s\n", pid, host, serv, myhost, myserv);*/ close(client); } } return 0; } </source> 55c2d7b51218335601e7c0aff666eb8426c91d61 分类:程序 14 17 41 2011-09-16T07:23:07Z HenryHu 1 以内容“这些是各种程序,一般指稍微复杂的东西,以及需要编译的东西。”创建新页面 wikitext text/x-wiki 这些是各种程序,一般指稍微复杂的东西,以及需要编译的东西。 fabac0241f748ed8a7ec3e23f7f5b638f013eb33 Splitape 0 18 42 2011-09-16T07:25:56Z HenryHu 1 以内容“[[Category:脚本]] splitape最早是用来分割APE文件的,现在稍微经过扩展,各种文件都能分割。 割完了能转成FLAC或其他格式,并且...”创建新页面 wikitext text/x-wiki [[Category:脚本]] splitape最早是用来分割APE文件的,现在稍微经过扩展,各种文件都能分割。 割完了能转成FLAC或其他格式,并且根据metadata进行命名,之后用easytag处理一下就能内嵌metadata了,例如id3v2或者flac的tag之类。 用到了[[shntool]]。 <source lang="bash"> #!/bin/sh if [ $# -le 1 ]; then echo "This tool would split ape file to flac file(s) according to cue sheet." echo "You may also specify other formats." echo "usage: $0 <cue file name> <ape file name> [<output format>]" exit 1 fi CUEFILE="$1" FILETYPE=`file "$1"` PA=`echo $FILETYPE | grep "ISO-8859"` PB=`echo $FILETYPE | grep "extended-ASCII"` PC=`echo $FILETYPE | grep "Non-ISO"` if [ "$PA" != "" -o "$PB" != "" -o "$PC" != "" ]; then echo "Found GBK-encoded CUE file, converting..." cat "$1" | iconv -f gbk > /tmp/splitape.cue.tmp CUEFILE=/tmp/splitape.cue.tmp fi if [ "$3" = "" ]; then OUTPUT_FORMAT="flac" elif [ "$3" = "mp3" ]; then OUTPUT_FORMAT="cust ext=mp3 lame - %f" else OUTPUT_FORMAT=$3 fi echo "CUE File: $1" echo "APE File: $2" shntool split -f "$CUEFILE" -t %n_%p_%a_%t -o "$OUTPUT_FORMAT" "$2" </source> c3b069da914371d68790352a1744221e95fc8820 Mntclean 0 19 43 2011-09-16T07:29:43Z HenryHu 1 以内容“[[Category:脚本]] FreeBSD上,在设备消失之后(例如拔下优盘之后),检查/mnt,并且清理下面内容的脚本。 配合[[devd]]使用。 <sou...”创建新页面 wikitext text/x-wiki [[Category:脚本]] FreeBSD上,在设备消失之后(例如拔下优盘之后),检查/mnt,并且清理下面内容的脚本。 配合[[devd]]使用。 <source lang="perl"> #!/usr/bin/perl sub logmsg { my ($msg) = @_; $msg =~ s/'/"/g; system("logger '[mntclean] $msg'"); } sub query_dev { my ($name) = @_; $namelen = 0; $ret = ""; $devs = `gpart list | grep Name`; foreach $i (split(/\n/, $devs)) { $i =~ m/.*?Name: (.*)$/; $dev = $1; $j =`glabel status $dev 2>&1`; if ($? eq 0) { foreach $line (split(/\n/, $j)) { if ($line =~ m/^$name /) { if (substr($line, 0, $namelen) == $name) { # In fact, maybe there are several # devices with the same label... # But what can we do... $ret = $dev; } } elsif ($line =~ m/^( *Name) *Status *Components$/) { $namepart = $1; $namelen = length($namepart); } } } } return $ret; } if (not $ARGV[0] =~ m!(.*)?/(.*)!) { print "Format error."; exit(1); } $parttype = $1; $partname = $2; $succ_sound = "/usr/local/share/wesnoth/sounds/arrive.wav"; $err_sound = "/usr/local/share/wesnoth/sounds/bell.wav"; logmsg("$partname removed, type: $parttype"); #foreach (glob("/mnt/*")) #{ # print $_; #} # system("/bin/rm -d /mnt/" . $partname); </source> 9cd72c1c328517b44ad846285ce1db85a84d14e7 Partmount 0 20 44 2011-09-16T07:33:14Z HenryHu 1 以内容“[[Category:脚本]] FreeBSD上,在设备插入(例如插了优盘)之后,根据信息自动挂载分区的脚本。 配合[[devd]]使用。 <source lang="per...”创建新页面 wikitext text/x-wiki [[Category:脚本]] FreeBSD上,在设备插入(例如插了优盘)之后,根据信息自动挂载分区的脚本。 配合[[devd]]使用。 <source lang="perl"> #!/usr/bin/perl sub logmsg { my ($msg) = @_; $msg =~ s/'/"/g; system("logger '[partmount] $msg'"); } sub query_dev { my ($name) = @_; $namelen = 0; $ret = ""; $devs = `gpart list | grep Name`; foreach $i (split(/\n/, $devs)) { $i =~ m/.*?Name: (.*)$/; $dev = $1; $j =`glabel status $dev 2>&1`; if ($? eq 0) { foreach $line (split(/\n/, $j)) { if ($line =~ m/^$name /) { if (substr($line, 0, $namelen) == $name) { # In fact, maybe there are several # devices with the same label... # But what can we do... $ret = $dev; } } elsif ($line =~ m/^( *Name) *Status *Components$/) { $namepart = $1; $namelen = length($namepart); } } } } return $ret; } if (not $ARGV[0] =~ m!(.*)?/(.*)!) { print "Format error."; exit(1); } $parttype = $1; $partname = $2; $devname = query_dev($ARGV[0]); $succ_sound = "/usr/local/share/wesnoth/sounds/arrive.wav"; $err_sound = "/usr/local/share/wesnoth/sounds/bell.wav"; logmsg("$partname inserted, type: $parttype, device: $devname"); if ($devname =~ m/^ad0/) { $result = ""; $retcode = -3; } elsif ($parttype =~ m/ntfs/) { mkdir("/mnt/$partname"); $result = `/usr/local/bin/ntfs-3g -o uid=1001,umask=022,fmask=133 /dev/$parttype/$partname /mnt/$partname 2>&1`; $retcode = $?; } elsif ($parttype =~ m/msdosfs/) { if ($partname =~ m/IPOD/) { $result = ""; $retcode = -2; } else { mkdir("/mnt/$partname"); $result = `/sbin/mount_msdosfs -m 775 -L zh_CN.UTF-8 -u 1001 /dev/$parttype/$partname /mnt/$partname 2>&1`; $retcode = $?; } } if ($retcode == 0) { logmsg("Mount successed."); system("/usr/local/bin/mplayer -really-quiet $succ_sound"); } elsif ($retcode == -3) { logmsg("Local partition found. Ignored.\n"); } elsif ($retcode == -2) { logmsg("Found iPod, ejecting.\n"); system("/sbin/camcontrol eject $devname"); } elsif ($retcode == -1) { logmsg("failed to execute: $!\n"); } elsif ($retcode & 127) { logmsg("Mount failed. child died with signal " . ($retcode & 127) . " , " . (($retcode & 128) ? 'with' : 'without') . " coredump\n"); logmsg("Child output: $result"); system("/usr/local/bin/mplayer -really-quiet $err_sound"); } else { logmsg("child exited with value " . ($retcode >> 8) . "\n"); logmsg("Child output: $result"); system("/usr/local/bin/mplayer -really-quiet $err_sound"); } </source> 241b2c6d8d36ee97d75af089260b2aab68b70f08 Say.sh 0 21 45 2011-09-16T07:35:25Z HenryHu 1 以内容“[[Category:脚本]] 脑残小脚本,用语音库简单地读东西。 曾经远程登录回宿舍的机子让它说话…… 当然,其实高级的TTS的东西...”创建新页面 wikitext text/x-wiki [[Category:脚本]] 脑残小脚本,用语音库简单地读东西。 曾经远程登录回宿舍的机子让它说话…… 当然,其实高级的TTS的东西很多…… 这个只是随便搞的…… <source lang="bash"> #!/bin/sh TPATH=/usr/local/share/WyabdcRealPeopleTTS/ #SENT="anyone hear me" #SENT="test remote sound play" #SENT="test remote sound play" #SENT="now the volume should be lower" #SENT="now the volume should be lower lower lower" #SENT="one five eight one zero eight five eight four two four" #SENT="my name as hen ray who" #SENT="hey don make me cry" SENT="big brother as watch in you" ERR=0 for i in $SENT; do FIRST=`echo $i | head -c 1` FPATH=$TPATH/$FIRST/$i.wav if [ ! -e $FPATH ]; then echo No $TPATH/$FIRST/$i.wav ERR=1 fi done FILES='' if [ "$ERR" = "0" ]; then echo OK for i in $SENT; do FIRST=`echo $i | head -c 1` FPATH=$TPATH/$FIRST/$i.wav if [ ! -e $FPATH ]; then echo No $TPATH/$FIRST/$i.wav ERR=2 else FILES="$FILES $FPATH" fi done fi mplayer -really-quiet $FILES </source> d6d6463c3307016fb8539904248aa261d9d6eb6a Fixwww 0 22 46 2011-09-16T07:39:28Z HenryHu 1 以内容“[[Category:脚本]] 简单的小脚本。 有时候你从网上下了一个东西,但是文件名是一堆奇怪的字母符号,包括A上有个点之类。 这...”创建新页面 wikitext text/x-wiki [[Category:脚本]] 简单的小脚本。 有时候你从网上下了一个东西,但是文件名是一堆奇怪的字母符号,包括A上有个点之类。 这个时候,就可以尝试这个…… 自动文件名修复…… <source lang="bash"> #!/bin/sh while [ "$1" != "" ]; do echo "$1" > /tmp/filename convmv --notest -f utf-8 -t iso8859-1 "$1" convmv --notest -f gbk -t utf-8 "`iconv -f utf-8 -t iso8859-1 /tmp/filename`" rm /tmp/filename shift done </source> 1356c0344b36716f71a8e1ff5010084e50fd3537 Getpkgsize 0 23 47 2011-09-16T07:41:15Z HenryHu 1 以内容“[[Category:脚本]] FreeBSD用小脚本,用来统计并显示各个包的空间占用。 很慢…… <source lang="perl"> #! /usr/bin/perl open(STDOUT,'| sort -n'...”创建新页面 wikitext text/x-wiki [[Category:脚本]] FreeBSD用小脚本,用来统计并显示各个包的空间占用。 很慢…… <source lang="perl"> #! /usr/bin/perl open(STDOUT,'| sort -n'); $sum=0; while(<STDIN>)#`pkg_info -s '*'`) { if (/^Pack/) { next; } unless (/for/ || /block/) { next; } if (/^Info/) { chop; /(^.*) (.*):$/; $x=$2; } else { chop; /(^\d+)/; $sum+=$1; print "$_ $x \n"; } } printf "%8d(1K-blocks) total\n",$sum; close(STDOUT); </source> 640246da5caa1644870e0d28c3aecb4909dc549f Sc 0 24 48 2011-09-16T07:42:53Z HenryHu 1 以内容“[[Category:脚本]] BSD用小脚本,自动帮你找到启动脚本并执行命令…… 这样既可以 sc powerd stop 也可以 sc nginx start 了。 <sou...”创建新页面 wikitext text/x-wiki [[Category:脚本]] BSD用小脚本,自动帮你找到启动脚本并执行命令…… 这样既可以 sc powerd stop 也可以 sc nginx start 了。 <source lang="bash"> #!/bin/sh if [ -f /etc/rc.d/$1 ]; then /etc/rc.d/$1 $2 elif [ -f /usr/local/etc/rc.d/$1 ]; then /usr/local/etc/rc.d/$1 $2 else echo "Cannout find service $1." fi </source> 8074f7301347fc643940bd8c0343a81ae99d547f KLEE 0 25 49 2011-09-16T17:28:27Z HenryHu 1 以内容“KLEE: 某用symbolic execution的方法来产生能够遍历不同程序路径的test cases的工具,可以找到bug。 == 编译 == 如果编译KLEE的时候说: ...”创建新页面 wikitext text/x-wiki KLEE: 某用symbolic execution的方法来产生能够遍历不同程序路径的test cases的工具,可以找到bug。 == 编译 == 如果编译KLEE的时候说: Bytecode libraries require LLVM capable compiler but none is available **** 那就是说,你的LLVM在configure的时候,没找到llvm-gcc。 基本上这是因为你没在编LLVM之前装llvm-gcc,或者装完了没加到path里去。 其实不加到path也可以,给configure加个参数,configure就不用自己到path里找llvm-gcc了。 加完了重新configure一下llvm,再编译安装就可以了。 4cab7ca6198ad72342d8a7f176b8cd39a3f6b8f8 50 49 2011-09-16T17:54:18Z HenryHu 1 wikitext text/x-wiki KLEE: 某用symbolic execution的方法来产生能够遍历不同程序路径的test cases的工具,可以找到bug。 == 编译 == 如果编译KLEE的时候说: Bytecode libraries require LLVM capable compiler but none is available **** 那就是说,你的LLVM在configure的时候,没找到llvm-gcc。 基本上这是因为你没在编LLVM之前装llvm-gcc,或者装完了没加到path里去。 其实不加到path也可以,给configure加个参数,configure就不用自己到path里找llvm-gcc了。 加完了重新configure一下llvm,再编译安装就可以了。 == 重现 == 重现的时候可能碰到这个问题: islower.c:(.text+0x3f): undefined reference to `klee_make_symbolic' 虽然你在链接里面已经加了libkleeRuntest.a。 如果你把它换成这个.a里那个唯一的.o,那就换个错误: In function `klee_make_symbolic': klee/runtime/Runtest/intrinsics.c:76: undefined reference to `kTest_fromFile' 于是如果你再把KTest.o加进来,那就可以编译过…… 问题在于: 1. 其实还依赖另一个.a,libkleeBasic.a 2. 顺序问题 我不知道为啥会有这个问题,或许以后会了解。反正现在知道的是,如果你用了.a的东西,你就要把.a放到后面。 所以要这么编译: gcc islower.c klee/lib/libkleeRuntest.a klee/lib/libkleeBasic.a -Iklee/include/ 然后就没问题了…… 57bed5e9e95d9bfc07e12eed8d12a2bb78cca443 KLEE 0 25 51 50 2011-09-16T17:54:38Z HenryHu 1 /* 重现 */ wikitext text/x-wiki KLEE: 某用symbolic execution的方法来产生能够遍历不同程序路径的test cases的工具,可以找到bug。 == 编译 == 如果编译KLEE的时候说: Bytecode libraries require LLVM capable compiler but none is available **** 那就是说,你的LLVM在configure的时候,没找到llvm-gcc。 基本上这是因为你没在编LLVM之前装llvm-gcc,或者装完了没加到path里去。 其实不加到path也可以,给configure加个参数,configure就不用自己到path里找llvm-gcc了。 加完了重新configure一下llvm,再编译安装就可以了。 == 重现 == 重现的时候可能碰到这个问题: islower.c:(.text+0x3f): undefined reference to `klee_make_symbolic' 虽然你在链接里面已经加了libkleeRuntest.a。 如果你把它换成这个.a里那个唯一的.o,那就换个错误: In function `klee_make_symbolic': klee/runtime/Runtest/intrinsics.c:76: undefined reference to `kTest_fromFile' 于是如果你再把KTest.o加进来,那就可以编译过…… 问题在于: 1. 其实还依赖另一个.a,libkleeBasic.a 2. 顺序问题 我不知道为啥会有这个问题,或许以后会了解。反正现在知道的是,如果你用了.a的东西,你就要把.a放到后面。 所以要这么编译: gcc islower.c klee/lib/libkleeRuntest.a klee/lib/libkleeBasic.a -Iklee/include/ 然后就没问题了…… 6124a22af7cf23c2aae92a7af24737297b993255 SubsConscious 0 3 52 6 2011-09-16T23:13:19Z HenryHu 1 wikitext text/x-wiki SubsConscious 是哥大边上,Amsterdam Av. 上的一个店,主营subs和salad SubsConscious: great food. great service. www.subsconscious.com === 评价 === * graduate 过来之后吃的第一种,挺好吃的,郭总推荐,郭总基本上只吃这个…… * lecture 本来我觉得是各种里面最好的,但是有一次有一个很不好吃。不过那个好像是拿错了,因为里面有炸鱼…… * ivy-league 好像不是很好吃…… * double-trouble 挺好吃的 * bar exam Jingyue推荐的,有beef,味道不错 * bronx-10461 刚开始吃感觉不错,不过吃到后来有奇怪的味道。貌似有汉堡里面那种蔬菜。 * twice-as-nice 挺不好吃的…… * valedictorian 不错,turkey系列之一,不过名字不好读 dcc529a6372af05323e3a127c272b15ca4b56e80 53 52 2011-09-23T22:57:54Z HenryHu 1 /* 评价 */ wikitext text/x-wiki SubsConscious 是哥大边上,Amsterdam Av. 上的一个店,主营subs和salad SubsConscious: great food. great service. www.subsconscious.com === 评价 === * graduate 过来之后吃的第一种,挺好吃的,郭总推荐,郭总基本上只吃这个…… * lecture 本来我觉得是各种里面最好的,但是有一次有一个很不好吃。不过那个好像是拿错了,因为里面有炸鱼…… 补充:那个的确拿错了,后来又吃了一次,的确很好吃 * ivy-league 好像不是很好吃…… * double-trouble 挺好吃的 * bar exam Jingyue推荐的,有beef,味道不错 * bronx-10461 刚开始吃感觉不错,不过吃到后来有奇怪的味道。貌似有汉堡里面那种蔬菜。 * twice-as-nice 挺不好吃的…… * valedictorian 不错,turkey系列之一,不过名字不好读 * iq 这就是上次lecture拿错的那个!不太好吃 * gpa 这个里面也有鱼,不过好像味道稍微好一些…… 等等,这个绿色的粘稠液体是啥…… 大概是蔬菜酱…… 幸好不是芥末…… acb5ff768daa54f9783256932b6baf9d5113cb4d 54 53 2011-09-23T23:07:56Z HenryHu 1 /* 评价 */ wikitext text/x-wiki SubsConscious 是哥大边上,Amsterdam Av. 上的一个店,主营subs和salad SubsConscious: great food. great service. www.subsconscious.com === 评价 === * graduate 过来之后吃的第一种,挺好吃的,郭总推荐,郭总基本上只吃这个…… * lecture 本来我觉得是各种里面最好的,但是有一次有一个很不好吃。不过那个好像是拿错了,因为里面有炸鱼…… 补充:那个的确拿错了,后来又吃了一次,的确很好吃 * ivy-league 好像不是很好吃…… * double-trouble 挺好吃的 * bar exam Jingyue推荐的,有beef,味道不错 * bronx-10461 刚开始吃感觉不错,不过吃到后来有奇怪的味道。貌似有汉堡里面那种蔬菜。 * twice-as-nice 挺不好吃的…… * valedictorian 不错,turkey系列之一,不过名字不好读 * iq 这就是上次lecture拿错的那个!不太好吃 * gpa 这个里面也有鱼,不过好像味道稍微好一些…… 等等,这个绿色的粘稠液体是啥…… 大概是蔬菜酱…… 幸好不是芥末…… 这个酱吃起来太恶心了…… 以后不要了…… a79d61fa75f8357de48efe97015108210bd7f481 55 54 2011-09-23T23:15:40Z HenryHu 1 wikitext text/x-wiki SubsConscious 是哥大边上,Amsterdam Av. 上的一个店,主营subs和salad SubsConscious: great food. great service. www.subsconscious.com === 关键词 === 材料:Turkey, Beef, Chicken 配料:Onion ??:America, Russia === 评价 === * graduate 过来之后吃的第一种,挺好吃的,郭总推荐,郭总基本上只吃这个…… * lecture 本来我觉得是各种里面最好的,但是有一次有一个很不好吃。不过那个好像是拿错了,因为里面有炸鱼…… 补充:那个的确拿错了,后来又吃了一次,的确很好吃 * ivy-league 好像不是很好吃…… * double-trouble 挺好吃的 * bar exam Jingyue推荐的,有beef,味道不错 * bronx-10461 刚开始吃感觉不错,不过吃到后来有奇怪的味道。貌似有汉堡里面那种蔬菜。 * twice-as-nice 挺不好吃的…… * valedictorian 不错,turkey系列之一,不过名字不好读 * iq 这就是上次lecture拿错的那个!不太好吃 * gpa 这个里面也有鱼,不过好像味道稍微好一些…… 等等,这个绿色的粘稠液体是啥…… 大概是蔬菜酱…… 幸好不是芥末…… 这个酱吃起来太恶心了…… 以后不要了…… 604a8f41cbdde4129a7f215e2bb437c808cf2e19 56 55 2011-09-23T23:15:52Z HenryHu 1 /* 关键词 */ wikitext text/x-wiki SubsConscious 是哥大边上,Amsterdam Av. 上的一个店,主营subs和salad SubsConscious: great food. great service. www.subsconscious.com === 关键词 === 材料:Turkey, Beef, Chicken 配料:Onion ??:America, Russia === 评价 === * graduate 过来之后吃的第一种,挺好吃的,郭总推荐,郭总基本上只吃这个…… * lecture 本来我觉得是各种里面最好的,但是有一次有一个很不好吃。不过那个好像是拿错了,因为里面有炸鱼…… 补充:那个的确拿错了,后来又吃了一次,的确很好吃 * ivy-league 好像不是很好吃…… * double-trouble 挺好吃的 * bar exam Jingyue推荐的,有beef,味道不错 * bronx-10461 刚开始吃感觉不错,不过吃到后来有奇怪的味道。貌似有汉堡里面那种蔬菜。 * twice-as-nice 挺不好吃的…… * valedictorian 不错,turkey系列之一,不过名字不好读 * iq 这就是上次lecture拿错的那个!不太好吃 * gpa 这个里面也有鱼,不过好像味道稍微好一些…… 等等,这个绿色的粘稠液体是啥…… 大概是蔬菜酱…… 幸好不是芥末…… 这个酱吃起来太恶心了…… 以后不要了…… eb5addc6706fb91524be38c4a1b4f54e29f6d5f5 68 56 2011-10-11T23:48:51Z HenryHu 1 wikitext text/x-wiki SubsConscious 是哥大边上,Amsterdam Av. 上的一个店,主营subs和salad SubsConscious: great food. great service. www.subsconscious.com === 关键词 === 材料:Turkey, Beef, Chicken 配料:Onion ??:America, Russia === 评价 === * graduate 过来之后吃的第一种,挺好吃的,郭总推荐,郭总基本上只吃这个…… * lecture 本来我觉得是各种里面最好的,但是有一次有一个很不好吃。不过那个好像是拿错了,因为里面有炸鱼…… 补充:那个的确拿错了,后来又吃了一次,的确很好吃 * ivy-league 好像不是很好吃…… * double-trouble 挺好吃的 * bar exam Jingyue推荐的,有beef,味道不错 * bronx-10461 刚开始吃感觉不错,不过吃到后来有奇怪的味道。貌似有汉堡里面那种蔬菜。 * twice-as-nice 挺不好吃的…… * valedictorian 不错,turkey系列之一,不过名字不好读 * iq 这就是上次lecture拿错的那个!不太好吃 * gpa 这个里面也有鱼,不过好像味道稍微好一些…… 等等,这个绿色的粘稠液体是啥…… 大概是蔬菜酱…… 幸好不是芥末…… 这个酱吃起来太恶心了…… 以后不要了…… * life-guard 终于凑满了10个,吃了个life guard 和graduate很像…… 不错 * triple-play 嗯,味道挺淡的。和lecture有点像,不过有好多青椒和生菜。一般。 480a7f8c52b22609c174ef480f0480da0d966703 74 68 2011-10-12T23:51:25Z HenryHu 1 wikitext text/x-wiki SubsConscious 是哥大边上,Amsterdam Av. 上的一个店,主营subs和salad SubsConscious: great food. great service. www.subsconscious.com === 关键词 === 材料:Turkey, Beef, Chicken 配料:Onion ??:America, Russia === 评价 === * graduate 过来之后吃的第一种,挺好吃的,郭总推荐,郭总基本上只吃这个…… * lecture 本来我觉得是各种里面最好的,但是有一次有一个很不好吃。不过那个好像是拿错了,因为里面有炸鱼…… 补充:那个的确拿错了,后来又吃了一次,的确很好吃 * ivy-league 好像不是很好吃…… * double-trouble 挺好吃的 * bar exam Jingyue推荐的,有beef,味道不错 * bronx-10461 刚开始吃感觉不错,不过吃到后来有奇怪的味道。貌似有汉堡里面那种蔬菜。 * twice-as-nice 挺不好吃的…… * valedictorian 不错,turkey系列之一,不过名字不好读 * iq 这就是上次lecture拿错的那个!不太好吃 * gpa 这个里面也有鱼,不过好像味道稍微好一些…… 等等,这个绿色的粘稠液体是啥…… 大概是蔬菜酱…… 幸好不是芥末…… 这个酱吃起来太恶心了…… 以后不要了…… * life-guard 终于凑满了10个,吃了个life guard 和graduate很像…… 不错 * triple-play 嗯,味道挺淡的。和lecture有点像,不过有好多青椒和生菜。一般。 * lions-den 非常好吃 * al's-advantage 比lions-den更好吃,基本上是最高水平 d160936e59032e8e21ae8be1b75b9178a58ffe2d 75 74 2011-10-15T01:22:52Z HenryHu 1 wikitext text/x-wiki SubsConscious 是哥大边上,Amsterdam Av. 上的一个店,主营subs和salad SubsConscious: great food. great service. www.subsconscious.com === 关键词 === 材料:Turkey, Beef, Chicken 配料:Onion ??:America, Russia === 评价 === * graduate 过来之后吃的第一种,挺好吃的,郭总推荐,郭总基本上只吃这个…… * lecture 本来我觉得是各种里面最好的,但是有一次有一个很不好吃。不过那个好像是拿错了,因为里面有炸鱼…… 补充:那个的确拿错了,后来又吃了一次,的确很好吃 * ivy-league 好像不是很好吃…… * double-trouble 挺好吃的 * bar exam Jingyue推荐的,有beef,味道不错 * bronx-10461 刚开始吃感觉不错,不过吃到后来有奇怪的味道。貌似有汉堡里面那种蔬菜。 * twice-as-nice 挺不好吃的…… * valedictorian 不错,turkey系列之一,不过名字不好读 * iq 这就是上次lecture拿错的那个!不太好吃 * gpa 这个里面也有鱼,不过好像味道稍微好一些…… 等等,这个绿色的粘稠液体是啥…… 大概是蔬菜酱…… 幸好不是芥末…… 这个酱吃起来太恶心了…… 以后不要了…… * life-guard 终于凑满了10个,吃了个life guard 和graduate很像…… 不错 * triple-play 嗯,味道挺淡的。和lecture有点像,不过有好多青椒和生菜。一般。 * lions-den 非常好吃 * al's-advantage 比lions-den更好吃,基本上是最高水平 今儿又吃了一次,的确不错,没有任何缺陷 其实挺像汉堡的味道…… ce8130158c074e86adea1afd4d3778c5212aee8d Blog Trend 0 26 57 2011-09-26T04:01:45Z HenryHu 1 以内容“Presentation的提纲…… * What is blog ** We used to write diary on notebooks ** Weblog: write dairy online ** So we can share our dairy with others * Origin ** E...”创建新页面 wikitext text/x-wiki Presentation的提纲…… * What is blog ** We used to write diary on notebooks ** Weblog: write dairy online ** So we can share our dairy with others * Origin ** Evolved from "online dairy" ** Started near 1994 ** People write on their own sites * Rise in popularity ** Spread during 1999 ** Using mature tools and blog sites, easier to write blogs ** Famous blog sites appear * Become mainstream ** Wide adoption starting from 2004 ** I started to blog in 2005. ** My classmates also started their blogs ** People use blogs to express their opinions ** Reporting news earlier than medias * Evolve ** People are losing patience ** Microblog: 140 words ** Social networks 6ed42d515c8c1b9376bb2f4fc92c815d46f2e76f 60 57 2011-09-26T04:21:53Z HenryHu 1 wikitext text/x-wiki Presentation的提纲…… * What is blog ** We used to write diary on notebooks ** Weblog: write dairy online ** So we can share our dairy with others * Origin ** Evolved from "online dairy" ** Started near 1994 ** People write on their own sites * Rise in popularity ** Spread during 1999 ** Using mature tools and blog sites, easier to write blogs ** Famous blog sites appear * Become mainstream ** Wide adoption starting from 2004 ** I started to blog in 2005. ** My classmates also started their blogs ** People use blogs to express their opinions ** Reporting news earlier than medias * Evolve ** People are losing patience ** Microblog: 140 words ** Social networks ** Fewer and fewer people write blogs * Impact ** Help people in recording their lives ** Developed an easy way for general people to spread opinions 545a9699a8355afc28335b0ad9490cbee19c7f52 61 60 2011-09-26T04:29:37Z HenryHu 1 wikitext text/x-wiki Presentation的提纲…… * What is blog ** We used to write diary on notebooks ** Weblog: write dairy online ** So we can share our dairy with others * Origin ** Evolved from "online dairy" ** Started near 1994 ** People write on their own sites * Rise in popularity ** Spread during 1999 ** Using mature tools and blog sites, easier to write blogs ** Famous blog sites appear * Become mainstream ** Wide adoption starting from 2004 ** I started to blog in 2005. ** My classmates also started their blogs ** People use blogs to express their opinions ** Reporting news earlier than medias * Evolve ** People are losing patience ** Fewer and fewer people write blogs ** Microblog: 140 words ** Social networks * Current status ** Many people abandoned their blogs * Impact ** Help people in recording their lives ** Developed an easy way for general people to spread opinions c1e1c05b378289078178ff798395bf888858b7b8 62 61 2011-09-26T04:31:20Z HenryHu 1 wikitext text/x-wiki Presentation的提纲…… * What is blog ** We used to write diary on notebooks ** Weblog: write dairy online ** So we can share our dairy with friends * Origin ** Evolved from "online dairy" ** Started near 1994 ** People write on their own sites * Rise in popularity ** Spread during 1999 ** Using mature tools and blog sites, easier to write blogs ** Famous blog sites appear * Become mainstream ** Wide adoption starting from 2004 ** I started to blog in 2005. ** My classmates also started their blogs ** People use blogs to express their opinions ** Reporting news earlier than medias * Evolve ** People are losing patience ** Fewer and fewer people write blogs ** Microblog: 140 words ** Social networks * Current status ** Many people abandoned their blogs * Impact ** Help people in recording their lives ** Developed an easy way for general people to spread opinions 645bb1f1b9a5ae4413adf82d7d1ca1536645ed5f 63 62 2011-09-26T04:51:00Z HenryHu 1 wikitext text/x-wiki Presentation的提纲…… * What is blog ** We used to write diary on notebooks ** Weblog: write dairy online ** So we can share our dairy with friends * Origin ** Evolved from "online dairy" ** Started near 1994 * Rise in popularity ** Spread during 1999 ** Mature tools developed, easy to write blogs ** Famous blog sites appear * Become mainstream ** Wide adoption starting from 2004 ** I started to blog in 2005. ** At the same time, My classmates also started their blogs ** Blog everything ** Reporting news earlier than medias * Evolve ** People are losing patience ** Fewer and fewer people write blogs ** Microblog: 140 words ** Social networks: Facebook * Current status ** As a consequence, Many people abandoned their blogs * Impact ** Help people in recording their lives ** Developed an easy way for general people to spread opinions 64d8b411378d6c5d2f38728efdc0081fc97a2876 64 63 2011-09-26T05:17:30Z HenryHu 1 wikitext text/x-wiki Presentation的提纲…… * What is blogging ** Old age: we used to write diary on dairy books ** Internet age: write dairy online ** Evolved from "online dairy" ** Started near 1994 ** So we can share our dairy with friends * Rise in popularity ** Spread during 1999 ** Mature tools developed, easy to write blogs ** Famous blog sites appear,thousands of people, familiar with blogs * Enter mainstream ** Wide adoption starting from 2004 ** I started to blog in 2005. ** At the same time, My classmates also started their blogs ** More and more people write blogs about everything ** Reporting news earlier than medias * Evolve ** People are losing patience ** Fewer and fewer people write blogs ** 1st move: Microblog: 140 words ** 2nd move: Social networks: Facebook * Current status ** As a consequence, many people abandoned their blogs * Impact ** Although blog lost its popularity ** Help people in recording their lives ** Developed an easy way for general people to spread opinions cebb42d18dd276b24c881de9a532c2008494cf04 HenryNotebook:版权信息 4 27 58 2011-09-26T04:15:12Z HenryHu 1 以内容“请注意,您对Henry's Notebook的所有贡献都被认为是在 Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported 协议下发布。 基...”创建新页面 wikitext text/x-wiki 请注意,您对Henry's Notebook的所有贡献都被认为是在 Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported 协议下发布。 基本上来说,就是如果要转载,请说明转载来自本Wiki;不得将本Wiki的内容用作商业用途;在将本Wiki的内容进行传播时,请根据相同的协议发布。 如果您不希望您的文字被任意修改和再散布,请不要提交。 4b408104cdc95b58bef5f13e087942d26cfcc278 HenryNotebook:免责声明 4 28 59 2011-09-26T04:19:26Z HenryHu 1 以内容“如果你因为看了本Wiki内容产生不适感,进而导致恶心、呕吐、喉咙干涩、手脚发凉、四肢无力、腰肌酸软、内分泌不调、椎间...”创建新页面 wikitext text/x-wiki 如果你因为看了本Wiki内容产生不适感,进而导致恶心、呕吐、喉咙干涩、手脚发凉、四肢无力、腰肌酸软、内分泌不调、椎间盘突出、颈椎病等状况,本人概不负责…… 如果对Wiki内容有意见,请在讨论页进行讨论。 0857f174382e6465b73b9ecb8950704b84bb82a3 Snapple 0 29 65 2011-10-11T03:48:19Z HenryHu 1 以内容“Snapple, 一种果汁饮料。 目前尝试过的: * RASPBERRY TEA *”创建新页面 wikitext text/x-wiki Snapple, 一种果汁饮料。 目前尝试过的: * RASPBERRY TEA * 799cb13382f8dffea8511ea0d1684b5ba0eb8ff0 66 65 2011-10-11T04:04:19Z HenryHu 1 wikitext text/x-wiki Snapple, 一种果汁饮料。 目前尝试过的: === Normal === * RASPBERRY TEA * LEMONADE * === Diet === c05a37cf5d444dae0d9219b8f406a7bfba84a54f 67 66 2011-10-11T23:23:29Z HenryHu 1 wikitext text/x-wiki Snapple, 一种果汁饮料。 目前尝试过的: === Normal === * RASPBERRY TEA * LEMONADE * KIWI STRAWBERRY * SNAPPLE APPLE * ORANGEADE === Diet === 86d46fcf64e60ea7b430f43c18ab32c739dfe4aa 73 67 2011-10-12T20:31:29Z HenryHu 1 wikitext text/x-wiki Snapple, 一种果汁饮料。 目前尝试过的: === Normal === * RASPBERRY TEA * LEMONADE * KIWI STRAWBERRY * SNAPPLE APPLE * ORANGEADE * ACAI BLACKBERRY === Diet === d1650f35dd5445ee7e2bc3bd63e06404fb350234 刷课机详解 0 30 69 2011-10-12T00:12:51Z HenryHu 1 以内容“代码: <source lang="python"> #!/usr/local/bin/python # vim: set fileencoding=utf8 : # 下面的东西反正是各种引用,有的或许还不需要…… import u...”创建新页面 wikitext text/x-wiki 代码: <source lang="python"> #!/usr/local/bin/python # vim: set fileencoding=utf8 : # 下面的东西反正是各种引用,有的或许还不需要…… import urllib2 import urllib import cookielib import lxml.html import subprocess import getpass import time import random from lxml import etree # 各种变量声明…… hosturl = "http://zhjwxk.cic.tsinghua.edu.cn"; # 用户名密码,密码还是当场输入比较安全 username = ""; password = getpass.getpass("Password: "); loginfrm = "https://zhjwxk.cic.tsinghua.edu.cn:443/j_acegi_formlogin_xsxk.do"; # 这个是在OCR之前执行的语句…… ocrcmd_pre = "convert captcha.jpg captcha.bmp ; cuneiform captcha.bmp > /dev/null"; #gocr -a 80 -s 100 -C \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\""; # 这句用来获取OCR结果…… ocrcmd_res = "cat cuneiform-out.txt"; urllogin = hosturl + "/xsxk_index.jsp"; # 有这几句就有Cookie支持了…… 请求之前会保留Cookie信息 jar = cookielib.CookieJar() handler = urllib2.HTTPCookieProcessor(jar) opener = urllib2.build_opener(handler) urllib2.install_opener(opener) h=urllib2.HTTPHandler(debuglevel=1) opener = urllib2.build_opener(h) # 另一些变量,主要是刷哪个课…… coursemajor = "30240422" courseminor = "0" term = "2010-2011-1" coursetype = "xx" # rx searchtype = "xxSearch" # rxSearch type_id = "p_xxk_id" # p_rx_id savetype = "saveXxKc" # saveRxKc arg2 = "?m=" + searchtype + "&p_xnxq=" + term + "&tokenPriFlag=" + coursetype + "&p_kch=" + coursemajor success = False trytime = 0 # 好,开工 while not success: # 先登录 while True: # 抓登录页面 data = urllib2.urlopen(urllogin).read() # print data; # 抓登录验证码图片的路径 img = lxml.html.fromstring(data).get_element_by_id("captcha"); # 抓验证码图片 captcha = urllib2.urlopen(hosturl + img.get("src")).read(); # 把图片写到文件用来OCR imgfile = open("captcha.jpg", "w"); imgfile.write(captcha); imgfile.close(); # 运行OCR之前要跑的东西 subprocess.Popen(args=ocrcmd_pre, shell=True).wait(); # 跑OCR程序 ocrproc = subprocess.Popen(args=ocrcmd_res, stdout=subprocess.PIPE, shell=True); # 拿结果,根据一般规律换掉一些OCR搞错的 ocrret = ocrproc.stdout.read().replace(" ","").replace("\n","").replace("/","J").replace("1","J").replace("I","J").replace("S","8"); # 构造登录的参数,用户名/密码/验证码等 loginfrm_arg = urllib.urlencode({'j_username': username, 'j_password': password, 'captchaflag': "login1", '_login_image_': ocrret}) loginres = "" try: # 尝试登录! loginres = urllib2.urlopen(loginfrm, loginfrm_arg).read(); except: loginres = "" if loginres.find("<div align=\"center\"") == -1 : # 成功了!否则再试…… break print "Logged in!" # print urllib2.urlopen(hosturl + "/xkBks.vxkBksXkbBs.do?m=rxSearch&p_xnxq=2010-2011-1&tokenPriFlag=rx&p_kch=00430093").read() # 抓登录之后的界面的一部分 mainpage = lxml.html.fromstring(urllib2.urlopen(hosturl + "/xkBks.vxkBksXkbBs.do" + arg2).read()) selurl = hosturl + "/" + mainpage.forms[0].action while True: trytime = trytime + 1 print "Round ", trytime seldict = {} try: # 枚举每个输入部分,看看哪些要处理 for input in mainpage.forms[0].inputs: if input.name != None and input.value != None: if input.name != 'submit1' and input.name != 'bt': print input.name.encode("utf-8"),":", input.value.encode("utf-8") # 有些是要填的 if input.name == 'm': input.value = savetype if (input.name == None): continue # 有些可以空着 if (input.value == None and input.name != 'j_captcha_bks_xk'): seldict[input.name] = '' continue # 一般的input需要原样返回,比如一些hidden的 if (input.type != 'button') & (input.type != 'reset') : seldict[input.name] = input.value # 恩,这个是验证码…… if input.name == 'j_captcha_bks_xk': # 有这个说明页面上要你填验证码了 img = mainpage.get_element_by_id("captcha"); # 抓验证码存下来 captcha = urllib2.urlopen(hosturl + img.get("src")).read(); imgfile = open("captcha.jpg", "w"); imgfile.write(captcha); imgfile.close(); # 老办法识别验证码 subprocess.Popen(args=ocrcmd_pre, shell=True).wait(); ocrproc = subprocess.Popen(args=ocrcmd_res, stdout=subprocess.PIPE, shell=True); ocrret = ocrproc.stdout.read().replace(" ","").replace("\n","").replace("/","J").replace("1","J").replace("I","J").replace("S","8"); # 把验证码填进去 seldict[input.name] = ocrret print "Img Capt: ",ocrret except: break # 要选啥课 seldict[type_id] = term + ";"+ coursemajor + ";" + courseminor + ";" # 构造选课时提交的参数 selparam = urllib.urlencode(seldict) print selparam # 过会,不急 time.sleep(0.5+0.01*random.randint(0, 100)) # 选课! selres = urllib2.urlopen(selurl, selparam).read().decode('gbk') # 把结果存下来,主要是调试用,另可以观察结果页面 selpage = open("selpage" + str(trytime % 2) + ".htm", "w"); selpage.write(selres.encode("utf-8")); selpage.close(); # 搞定了? if selres.encode("utf-8").find("成功") != -1: success = True; break # 悲剧了,重新登陆吧,多半超时了 if selres.encode("utf-8").find("Forbidden") != -1: timeout = True; break; # 别的问题,多半是满了 mainpage = lxml.html.fromstring(selres) alertStart = selres.find('showMsg("') + 9; alertEnd = selres.find('");', alertStart); print "Result: ", selres[alertStart:alertEnd] # print selres.encode("utf-8") # 全部完成! print "FINISHED!" </source> f9db954b84395385b4f5085d48650d3a3436bd1b 71 69 2011-10-12T00:38:02Z HenryHu 1 wikitext text/x-wiki 关于这个刷课机是如何工作的 == 代码 == <source lang="python"> #!/usr/local/bin/python # vim: set fileencoding=utf8 : # 下面的东西反正是各种引用,有的或许还不需要…… import urllib2 import urllib import cookielib import lxml.html import subprocess import getpass import time import random from lxml import etree # 各种变量声明…… hosturl = "http://zhjwxk.cic.tsinghua.edu.cn"; # 用户名密码,密码还是当场输入比较安全 username = ""; password = getpass.getpass("Password: "); loginfrm = "https://zhjwxk.cic.tsinghua.edu.cn:443/j_acegi_formlogin_xsxk.do"; # 这个是在OCR之前执行的语句…… ocrcmd_pre = "convert captcha.jpg captcha.bmp ; cuneiform captcha.bmp > /dev/null"; #gocr -a 80 -s 100 -C \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\""; # 这句用来获取OCR结果…… ocrcmd_res = "cat cuneiform-out.txt"; urllogin = hosturl + "/xsxk_index.jsp"; # 有这几句就有Cookie支持了…… 请求之前会保留Cookie信息 jar = cookielib.CookieJar() handler = urllib2.HTTPCookieProcessor(jar) opener = urllib2.build_opener(handler) urllib2.install_opener(opener) h=urllib2.HTTPHandler(debuglevel=1) opener = urllib2.build_opener(h) # 另一些变量,主要是刷哪个课…… coursemajor = "30240422" courseminor = "0" term = "2010-2011-1" coursetype = "xx" # rx searchtype = "xxSearch" # rxSearch type_id = "p_xxk_id" # p_rx_id savetype = "saveXxKc" # saveRxKc arg2 = "?m=" + searchtype + "&p_xnxq=" + term + "&tokenPriFlag=" + coursetype + "&p_kch=" + coursemajor success = False trytime = 0 # 好,开工 while not success: # 先登录 while True: # 抓登录页面 data = urllib2.urlopen(urllogin).read() # print data; # 抓登录验证码图片的路径 img = lxml.html.fromstring(data).get_element_by_id("captcha"); # 抓验证码图片 captcha = urllib2.urlopen(hosturl + img.get("src")).read(); # 把图片写到文件用来OCR imgfile = open("captcha.jpg", "w"); imgfile.write(captcha); imgfile.close(); # 运行OCR之前要跑的东西 subprocess.Popen(args=ocrcmd_pre, shell=True).wait(); # 跑OCR程序 ocrproc = subprocess.Popen(args=ocrcmd_res, stdout=subprocess.PIPE, shell=True); # 拿结果,根据一般规律换掉一些OCR搞错的 ocrret = ocrproc.stdout.read().replace(" ","").replace("\n","").replace("/","J").replace("1","J").replace("I","J").replace("S","8"); # 构造登录的参数,用户名/密码/验证码等 loginfrm_arg = urllib.urlencode({'j_username': username, 'j_password': password, 'captchaflag': "login1", '_login_image_': ocrret}) loginres = "" try: # 尝试登录! loginres = urllib2.urlopen(loginfrm, loginfrm_arg).read(); except: loginres = "" if loginres.find("<div align=\"center\"") == -1 : # 成功了!否则再试…… break print "Logged in!" # print urllib2.urlopen(hosturl + "/xkBks.vxkBksXkbBs.do?m=rxSearch&p_xnxq=2010-2011-1&tokenPriFlag=rx&p_kch=00430093").read() # 抓登录之后的界面的一部分 mainpage = lxml.html.fromstring(urllib2.urlopen(hosturl + "/xkBks.vxkBksXkbBs.do" + arg2).read()) selurl = hosturl + "/" + mainpage.forms[0].action while True: trytime = trytime + 1 print "Round ", trytime seldict = {} try: # 枚举每个输入部分,看看哪些要处理 for input in mainpage.forms[0].inputs: if input.name != None and input.value != None: if input.name != 'submit1' and input.name != 'bt': print input.name.encode("utf-8"),":", input.value.encode("utf-8") # 有些是要填的 if input.name == 'm': input.value = savetype if (input.name == None): continue # 有些可以空着 if (input.value == None and input.name != 'j_captcha_bks_xk'): seldict[input.name] = '' continue # 一般的input需要原样返回,比如一些hidden的 if (input.type != 'button') & (input.type != 'reset') : seldict[input.name] = input.value # 恩,这个是验证码…… if input.name == 'j_captcha_bks_xk': # 有这个说明页面上要你填验证码了 img = mainpage.get_element_by_id("captcha"); # 抓验证码存下来 captcha = urllib2.urlopen(hosturl + img.get("src")).read(); imgfile = open("captcha.jpg", "w"); imgfile.write(captcha); imgfile.close(); # 老办法识别验证码 subprocess.Popen(args=ocrcmd_pre, shell=True).wait(); ocrproc = subprocess.Popen(args=ocrcmd_res, stdout=subprocess.PIPE, shell=True); ocrret = ocrproc.stdout.read().replace(" ","").replace("\n","").replace("/","J").replace("1","J").replace("I","J").replace("S","8"); # 把验证码填进去 seldict[input.name] = ocrret print "Img Capt: ",ocrret except: break # 要选啥课 seldict[type_id] = term + ";"+ coursemajor + ";" + courseminor + ";" # 构造选课时提交的参数 selparam = urllib.urlencode(seldict) print selparam # 过会,不急 time.sleep(0.5+0.01*random.randint(0, 100)) # 选课! selres = urllib2.urlopen(selurl, selparam).read().decode('gbk') # 把结果存下来,主要是调试用,另可以观察结果页面 selpage = open("selpage" + str(trytime % 2) + ".htm", "w"); selpage.write(selres.encode("utf-8")); selpage.close(); # 搞定了? if selres.encode("utf-8").find("成功") != -1: success = True; break # 悲剧了,重新登陆吧,多半超时了 if selres.encode("utf-8").find("Forbidden") != -1: timeout = True; break; # 别的问题,多半是满了 mainpage = lxml.html.fromstring(selres) alertStart = selres.find('showMsg("') + 9; alertEnd = selres.find('");', alertStart); print "Result: ", selres[alertStart:alertEnd] # print selres.encode("utf-8") # 全部完成! print "FINISHED!" </source> == 主要用到的方法 == 其实还包括用到的成员变量 === 如何抓页面及提交请求 === * urllib2.urlopen(url) 非常好用的方法,用HTTP抓某个页面。这个样子会用HTTP GET抓。 对返回的东西调用read()就会返回整个页面,在一个字符串里,想干嘛都可以。 * urllib2.urlopen(url, param) 这个样子会用HTTP POST提交某个页面,一般点按钮之类都会提交某个form,这个时候用的多半都是HTTP POST方法。 所以比如登录啦、选课啦都是POST方法,而获取登录页面啦、获取选课页面啦都是GET。 * urllib.urlencode(dict) 给他一个dict,就能返回一个可以给上面那个方法用的param。 * 关于Cookie的那四行 反正就是给系统一个存Cookie的地方,并且让系统用它。这样各个请求的Cookie信息会保留,在下一个请求用。 === HTML页面的分析 === * lxml.html.fromstring(string) lxml是个很方便的分析XML/HTML的库,这个方法能够读一个string,返回一个html对象,里面是HTML文档处理之后得到的结构化的结果。然后在这个对象上就能干各种事情了。以下把其返回的叫html。 * html.get_element_by_id(id) 有了上面那个的结构化的结果,就能在里面找某个特定id的对象了。 * html.forms[] 包括了该页所有form的数组,一般你要找的form就在其中…… 以下把其成员称为form * form.inputs 某form的所有输入,一般我们只关心这个…… 以下把其成员称为input * input.value, input.name 某输入项的值与名字。你可以拿去用,在提交的时候还要交回去。一般提交的时候,参数里都有 名字=值 这样的好多对。 * string.decode(encoding), string.encode(encoding) 反正是用来转编码的,陌生的字符串最好decode一下,要find东西的时候最好encode一下 === 子进程相关 === * subprocess.Popen(args=cmd, shell=True) 开一个进程跑某物,要不要shell有时候不一样。以下把其返回的叫proc * proc.wait() 等某进程结束,这样才好拿它输出的东西。 * proc.stdout() 某进程的输出,用.read()可以全读到一个字符串里。 fd9058e0a5fb4cc20940b211c3d396ed145d3387 72 71 2011-10-12T00:38:25Z HenryHu 1 wikitext text/x-wiki 关于这个[[刷课机]]是如何工作的 == 代码 == <source lang="python"> #!/usr/local/bin/python # vim: set fileencoding=utf8 : # 下面的东西反正是各种引用,有的或许还不需要…… import urllib2 import urllib import cookielib import lxml.html import subprocess import getpass import time import random from lxml import etree # 各种变量声明…… hosturl = "http://zhjwxk.cic.tsinghua.edu.cn"; # 用户名密码,密码还是当场输入比较安全 username = ""; password = getpass.getpass("Password: "); loginfrm = "https://zhjwxk.cic.tsinghua.edu.cn:443/j_acegi_formlogin_xsxk.do"; # 这个是在OCR之前执行的语句…… ocrcmd_pre = "convert captcha.jpg captcha.bmp ; cuneiform captcha.bmp > /dev/null"; #gocr -a 80 -s 100 -C \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\""; # 这句用来获取OCR结果…… ocrcmd_res = "cat cuneiform-out.txt"; urllogin = hosturl + "/xsxk_index.jsp"; # 有这几句就有Cookie支持了…… 请求之前会保留Cookie信息 jar = cookielib.CookieJar() handler = urllib2.HTTPCookieProcessor(jar) opener = urllib2.build_opener(handler) urllib2.install_opener(opener) h=urllib2.HTTPHandler(debuglevel=1) opener = urllib2.build_opener(h) # 另一些变量,主要是刷哪个课…… coursemajor = "30240422" courseminor = "0" term = "2010-2011-1" coursetype = "xx" # rx searchtype = "xxSearch" # rxSearch type_id = "p_xxk_id" # p_rx_id savetype = "saveXxKc" # saveRxKc arg2 = "?m=" + searchtype + "&p_xnxq=" + term + "&tokenPriFlag=" + coursetype + "&p_kch=" + coursemajor success = False trytime = 0 # 好,开工 while not success: # 先登录 while True: # 抓登录页面 data = urllib2.urlopen(urllogin).read() # print data; # 抓登录验证码图片的路径 img = lxml.html.fromstring(data).get_element_by_id("captcha"); # 抓验证码图片 captcha = urllib2.urlopen(hosturl + img.get("src")).read(); # 把图片写到文件用来OCR imgfile = open("captcha.jpg", "w"); imgfile.write(captcha); imgfile.close(); # 运行OCR之前要跑的东西 subprocess.Popen(args=ocrcmd_pre, shell=True).wait(); # 跑OCR程序 ocrproc = subprocess.Popen(args=ocrcmd_res, stdout=subprocess.PIPE, shell=True); # 拿结果,根据一般规律换掉一些OCR搞错的 ocrret = ocrproc.stdout.read().replace(" ","").replace("\n","").replace("/","J").replace("1","J").replace("I","J").replace("S","8"); # 构造登录的参数,用户名/密码/验证码等 loginfrm_arg = urllib.urlencode({'j_username': username, 'j_password': password, 'captchaflag': "login1", '_login_image_': ocrret}) loginres = "" try: # 尝试登录! loginres = urllib2.urlopen(loginfrm, loginfrm_arg).read(); except: loginres = "" if loginres.find("<div align=\"center\"") == -1 : # 成功了!否则再试…… break print "Logged in!" # print urllib2.urlopen(hosturl + "/xkBks.vxkBksXkbBs.do?m=rxSearch&p_xnxq=2010-2011-1&tokenPriFlag=rx&p_kch=00430093").read() # 抓登录之后的界面的一部分 mainpage = lxml.html.fromstring(urllib2.urlopen(hosturl + "/xkBks.vxkBksXkbBs.do" + arg2).read()) selurl = hosturl + "/" + mainpage.forms[0].action while True: trytime = trytime + 1 print "Round ", trytime seldict = {} try: # 枚举每个输入部分,看看哪些要处理 for input in mainpage.forms[0].inputs: if input.name != None and input.value != None: if input.name != 'submit1' and input.name != 'bt': print input.name.encode("utf-8"),":", input.value.encode("utf-8") # 有些是要填的 if input.name == 'm': input.value = savetype if (input.name == None): continue # 有些可以空着 if (input.value == None and input.name != 'j_captcha_bks_xk'): seldict[input.name] = '' continue # 一般的input需要原样返回,比如一些hidden的 if (input.type != 'button') & (input.type != 'reset') : seldict[input.name] = input.value # 恩,这个是验证码…… if input.name == 'j_captcha_bks_xk': # 有这个说明页面上要你填验证码了 img = mainpage.get_element_by_id("captcha"); # 抓验证码存下来 captcha = urllib2.urlopen(hosturl + img.get("src")).read(); imgfile = open("captcha.jpg", "w"); imgfile.write(captcha); imgfile.close(); # 老办法识别验证码 subprocess.Popen(args=ocrcmd_pre, shell=True).wait(); ocrproc = subprocess.Popen(args=ocrcmd_res, stdout=subprocess.PIPE, shell=True); ocrret = ocrproc.stdout.read().replace(" ","").replace("\n","").replace("/","J").replace("1","J").replace("I","J").replace("S","8"); # 把验证码填进去 seldict[input.name] = ocrret print "Img Capt: ",ocrret except: break # 要选啥课 seldict[type_id] = term + ";"+ coursemajor + ";" + courseminor + ";" # 构造选课时提交的参数 selparam = urllib.urlencode(seldict) print selparam # 过会,不急 time.sleep(0.5+0.01*random.randint(0, 100)) # 选课! selres = urllib2.urlopen(selurl, selparam).read().decode('gbk') # 把结果存下来,主要是调试用,另可以观察结果页面 selpage = open("selpage" + str(trytime % 2) + ".htm", "w"); selpage.write(selres.encode("utf-8")); selpage.close(); # 搞定了? if selres.encode("utf-8").find("成功") != -1: success = True; break # 悲剧了,重新登陆吧,多半超时了 if selres.encode("utf-8").find("Forbidden") != -1: timeout = True; break; # 别的问题,多半是满了 mainpage = lxml.html.fromstring(selres) alertStart = selres.find('showMsg("') + 9; alertEnd = selres.find('");', alertStart); print "Result: ", selres[alertStart:alertEnd] # print selres.encode("utf-8") # 全部完成! print "FINISHED!" </source> == 主要用到的方法 == 其实还包括用到的成员变量 === 如何抓页面及提交请求 === * urllib2.urlopen(url) 非常好用的方法,用HTTP抓某个页面。这个样子会用HTTP GET抓。 对返回的东西调用read()就会返回整个页面,在一个字符串里,想干嘛都可以。 * urllib2.urlopen(url, param) 这个样子会用HTTP POST提交某个页面,一般点按钮之类都会提交某个form,这个时候用的多半都是HTTP POST方法。 所以比如登录啦、选课啦都是POST方法,而获取登录页面啦、获取选课页面啦都是GET。 * urllib.urlencode(dict) 给他一个dict,就能返回一个可以给上面那个方法用的param。 * 关于Cookie的那四行 反正就是给系统一个存Cookie的地方,并且让系统用它。这样各个请求的Cookie信息会保留,在下一个请求用。 === HTML页面的分析 === * lxml.html.fromstring(string) lxml是个很方便的分析XML/HTML的库,这个方法能够读一个string,返回一个html对象,里面是HTML文档处理之后得到的结构化的结果。然后在这个对象上就能干各种事情了。以下把其返回的叫html。 * html.get_element_by_id(id) 有了上面那个的结构化的结果,就能在里面找某个特定id的对象了。 * html.forms[] 包括了该页所有form的数组,一般你要找的form就在其中…… 以下把其成员称为form * form.inputs 某form的所有输入,一般我们只关心这个…… 以下把其成员称为input * input.value, input.name 某输入项的值与名字。你可以拿去用,在提交的时候还要交回去。一般提交的时候,参数里都有 名字=值 这样的好多对。 * string.decode(encoding), string.encode(encoding) 反正是用来转编码的,陌生的字符串最好decode一下,要find东西的时候最好encode一下 === 子进程相关 === * subprocess.Popen(args=cmd, shell=True) 开一个进程跑某物,要不要shell有时候不一样。以下把其返回的叫proc * proc.wait() 等某进程结束,这样才好拿它输出的东西。 * proc.stdout() 某进程的输出,用.read()可以全读到一个字符串里。 c6f188fc62ac03aea1bfc8fabad1f8bd00fde01d 刷课机 0 4 70 24 2011-10-12T00:16:53Z HenryHu 1 wikitext text/x-wiki [[Category:脚本|coursel]] 刷课机,一般指通过模拟用户操作,不断选课,从而试图选上某一门课的用于选课的程序。 以下列出了一些我写的刷课机…… == 清华刷课机 == 链接:[[文件:coursel.py|coursel.py]] 其实写刷课机也是个学习python的过程…… 清华的验证码比较复杂。为了识别这个验证码,用到了cuneiform。其实gocr的效果也不错。 对这个刷课机的详细分析,可见[[刷课机详解]] == 北大刷课机 == 链接:[[文件:coursel_pku.py]] 链接:[[文件:pointrmv.cpp]] 链接:[[文件:c_pku.tar.gz]] 在清华的基础上改的,结构基本相同…… 另外,这里引用了一个文件,pointrmv。北大的验证码太弱智了,所以自己搞了个简单的程序用来识别验证码…… 这个验证码识别工具还用到了一些标准图像,从北大验证码里截的…… 这些在那个压缩包里。其实那个包里也有另外两个文件…… === 验证码识别 === 北大的验证码实在太弱,基本上就加了些噪点,别的没了…… 所以识别程序先去掉那些点,然后匹配图片就完了。 用了libjpeg来载入图片。噪点识别好像就是看看深浅,太久了,忘了…… 反正很弱…… === 某人被抓事件 === 好像某人拿我的刷课机在北大刷课的时候被抓了。然后他们那边的老师还让他交出源代码啥的。 但是其实不是他自己刷,而是我在清华访问北大网络刷课。因此,他也没有源代码。后来他联系我,说老师只要他交出源代码就不追究了。 其实这个刷课机也没啥技术含量对吧…… 所以我记得我就给他了。 后来就没有消息了,北大的系统好像还是很烂。 30893835cefb0b3ea83f0ca967022e5318bc8a61 模板:Yes 10 31 76 2011-11-06T00:46:17Z HenryHu 1 以内容“<noinclude>{| class="wikitable" |- |</noinclude>style="background: #90ff90; color: black; vertical-align: middle; text-align: {{{align|center}}}; {{{style|}}}" class="t...”创建新页面 wikitext text/x-wiki <noinclude>{| class="wikitable" |- |</noinclude>style="background: #90ff90; color: black; vertical-align: middle; text-align: {{{align|center}}}; {{{style|}}}" class="table-yes"|{{{1|Yes}}}<noinclude> |} {{documentation}} </noinclude> 066bb2836075b8428e0145d9d4dca2198ddcb347 模板:No 10 32 77 2011-11-06T00:50:21Z HenryHu 1 以内容“<noinclude>{| class="wikitable" |- |</noinclude>style="background:#ff9090; color:black; vertical-align: middle; text-align: {{{align|center}}}; {{{style|}}}" class="tab...”创建新页面 wikitext text/x-wiki <noinclude>{| class="wikitable" |- |</noinclude>style="background:#ff9090; color:black; vertical-align: middle; text-align: {{{align|center}}}; {{{style|}}}" class="table-no" | {{{1|No}}}<noinclude> |} {{documentation}} </noinclude> 8e6144d2202a76bdf9ba5fe6b50db715d1a78f07 Android FTP Client 0 33 78 2011-11-06T00:50:32Z HenryHu 1 以内容“A comparison between Android FTP clients {| class="wikitable" |- | | AndFTP | FtpCafe | AbyssFTP |- | Support GBK | {{Yes}} | {{No}} | {{No}} |}”创建新页面 wikitext text/x-wiki A comparison between Android FTP clients {| class="wikitable" |- | | AndFTP | FtpCafe | AbyssFTP |- | Support GBK | {{Yes}} | {{No}} | {{No}} |} 06ad718019a62b93d3b0c9024e68f88466212a2c 79 78 2011-11-06T00:56:05Z HenryHu 1 wikitext text/x-wiki A comparison between Android FTP clients {| class="wikitable" |- ! || AndFTP || FtpCafe || AbyssFTP |- | Support GBK || {{Yes}} || {{No}} || {{No}} |- | Resume || {{Yes}} || {{Yes}} || {{Yes}} |- | Support SFTP || {{Yes}} |- | Support FTPS || {{Yes}} |- | GUI || {{No|Ugly}} || {{No|Ugly}} || {{No|Ugly}} |} e24909cafd211a843daba9f50d5c085b8cb99f2c 80 79 2011-11-06T00:57:07Z HenryHu 1 wikitext text/x-wiki A comparison between Android FTP clients {| class="wikitable" |- ! || AndFTP || FtpCafe || AbyssFTP |- | Support GBK || {{Yes}} || {{No}} || {{No}} |- | Resume || {{Yes}} || {{Yes}} || {{Yes}} |- | Support SFTP || {{Yes}} || {{Yes}} |- | Support FTPS || {{Yes}} || {{Yes}} |- | GUI || {{No|Ugly}} || {{No|Ugly}} || {{No|Ugly}} |} a2aff360223382af4c92d78fe0776c40f8998608 NAT 0 34 81 2011-11-08T06:05:34Z HenryHu 1 以内容“NAT,全称Network Address Translation,网络地址转换。 是一种使得内网的计算机可以访问外网的技术。 这个本来是写在Net9 Wiki上的...”创建新页面 wikitext text/x-wiki NAT,全称Network Address Translation,网络地址转换。 是一种使得内网的计算机可以访问外网的技术。 这个本来是写在Net9 Wiki上的,现在这里也弄一份…… ==基础== 是在[[网关]]上进行的一种过程,是在转发数据包的过程中干的。 因此,依赖于[[网关]]的功能。 ==样例与分析== ===环境=== * 有某内网,网段192.168.1.0,网络掩码255.255.255.0。 * 其中有某机,IP 192.168.137.3。 * 网关对内IP 192.168.137.1。 * 网关对外IP 59.66.132.114。 * 网关对外环境下的默认路由IP 59.66.132.1。 ===目的=== 某机想上网,访问ibm.com的80端口。 ===常量定义=== A: ibm.com 的IP地址 B: 某机IP(192.168.137.3) C: 网关对外IP(59.66.132.114) D: 网关IP(192.168.137.1) a: 网关内网接口的MAC地址(对应192.168.137.1) b: 网关外网上默认路由的MAC地址(对应59.66.132.1) c: 某机MAC地址(对应192.168.137.3) d: 网关外网接口MAC地址(对应59.66.132.114) x: 某机认为的源端口 y: 经过NAT变换之后的源端口 m: ibm.com 域名 ===数据包=== 某机发出的开始连接TCP数据包: {| |- ! MAC头 !! IP头 !! TCP头 |- | a<-c || A<-B || 80<-x |} 于是这个包被网关收到,经过篡改,当它在外网出现的时候,成了这样: {| |- ! MAC头 !! IP头 !! TCP头 |- | b<-d || A<-C || 80<-y |} 对面收到之后发了回复,回复抵达网关的外网接口的时候,是这样: {| |- ! MAC头 !! IP头 !! TCP头 |- | d<-b || C<-A || y<-80 |} 然后又被篡改,当某机收到的时候,是这样: {| |- ! MAC头 !! IP头 !! TCP头 |- | c<-a || B<-A || x<-80 |} 对某机来说,看上去就有了一条A:80 <-> B:x的连接。 但是对对面来说,看上去其实是有一条A:80 <-> C:y的连接。 ===分析=== 为啥要篡改?因为如果在外网出现了一个192.168.137.3的数据包,谁知道这个包是干啥的,因为外网的网段是59.66.132.0/24,不应该有这种包。所以就会被扔掉,即使没有扔掉,回复也发不回来。 所以,要伪造成网关发出去的包才有人管。所以,首先要把IP篡改成网关的对外IP。 当对面收到并且发了回复回来的时候,还需要改回去。问题是,如何区分哪些包是应该改的?对于TCP/UDP包,有个很好的依据:端口号。 所以,只要在之前篡改的时候,记录下源端口号,和源IP,那么当收到数据包的时候,如果目的端口号就是记下的这个,那就篡改回去,并且发给记下来的来源地址。 简单来说,这样就可以了。MAC地址那边的变化,只是为了数据包能够抵达目的地而已。这方面可以参考基础的[[网关]]转发数据包的过程。 那么为啥有时候还要篡改端口号?因为可能,网关对外出口上,已经有一个程序在用这个端口号了。比如有一个人listen在1025端口上,而内网的一个机子发给外网一个数据包,源端口号也是1025。那么,当有一个新的数据包到来,并且其目的端口号是1025的时候,我们要不要篡改呢?我们怎么知道,这个是到那个listen的人的一个新连接,还是对原来内网那个数据包的回应呢? 所以,有时候要篡改一下端口号,同时记录下源IP和源端口号,以及篡改后的端口号。这样,当收到向篡改后的端口号发送的数据包的时候,我们就要把目的地址和目的端口都篡改回去,再发给原来的发送者。 7822652941f9dcfd463827de102010e93d86d432 Package Management 0 35 82 2011-11-18T06:08:05Z HenryHu 1 以内容“Package Management,也就是包管理 其实常用命令就那几个…… 所以列一下吧 == 查找包名 === * pacman: # pacman -Ss <string> * ports: # psearc...”创建新页面 wikitext text/x-wiki Package Management,也就是包管理 其实常用命令就那几个…… 所以列一下吧 == 查找包名 === * pacman: # pacman -Ss <string> * ports: # psearch <string> * apt / dpkg: # apt-cache search <string> * yum / rpm: # yum search <string> == 查询文件属于那个包 == === 已安装 === * pacman: # pacman -Q -o <path> * ports: # pkg_info -W <path> # pkg_which <path> * apt / dpkg # dpkg -S /usr/bin/ipmitool * yum / rpm: # rpm -q -f <path> === 未安装 === Google <file name> == 列出某包文件列表 == * pacman: # pacman -Q -l <package name> * ports: # pkg_info -L <package name with package version> # pkg_info -L <package name>-\* // hackish! * apt / dpkg: # dpkg -L <package name> * yum / rpm: # rpm -q -l <package name> == 装 == * pacman: # pacman -S <package name> * ports: # pkg_add -r <package name> # portinstall -PPv <package name> # cd <package path>; make install * apt / dpkg: # apt-get install <package name> * yum / rpm: # yum install <package name> == 删 == * pacman: # pacman -R <package name> * ports: # pkg_delete <package name with version> * apt / dpkg: # apt-get remove <package name> * yum / rpm: # yum remove <package name> 1d107870fee55aa73ed8037aa4180464d71550f6 83 82 2011-11-18T06:08:28Z HenryHu 1 /* 查找包名 = */ wikitext text/x-wiki Package Management,也就是包管理 其实常用命令就那几个…… 所以列一下吧 == 根据名字查找包 == * pacman: # pacman -Ss <string> * ports: # psearch <string> * apt / dpkg: # apt-cache search <string> * yum / rpm: # yum search <string> == 查询文件属于那个包 == === 已安装 === * pacman: # pacman -Q -o <path> * ports: # pkg_info -W <path> # pkg_which <path> * apt / dpkg # dpkg -S /usr/bin/ipmitool * yum / rpm: # rpm -q -f <path> === 未安装 === Google <file name> == 列出某包文件列表 == * pacman: # pacman -Q -l <package name> * ports: # pkg_info -L <package name with package version> # pkg_info -L <package name>-\* // hackish! * apt / dpkg: # dpkg -L <package name> * yum / rpm: # rpm -q -l <package name> == 装 == * pacman: # pacman -S <package name> * ports: # pkg_add -r <package name> # portinstall -PPv <package name> # cd <package path>; make install * apt / dpkg: # apt-get install <package name> * yum / rpm: # yum install <package name> == 删 == * pacman: # pacman -R <package name> * ports: # pkg_delete <package name with version> * apt / dpkg: # apt-get remove <package name> * yum / rpm: # yum remove <package name> 3e3270396a1c4e263f351cbcfb184c187498e52d 84 83 2011-11-18T06:08:58Z HenryHu 1 /* 已安装 */ wikitext text/x-wiki Package Management,也就是包管理 其实常用命令就那几个…… 所以列一下吧 == 根据名字查找包 == * pacman: # pacman -Ss <string> * ports: # psearch <string> * apt / dpkg: # apt-cache search <string> * yum / rpm: # yum search <string> == 查询文件属于那个包 == === 已安装 === * pacman: # pacman -Q -o <path> * ports: # pkg_info -W <path> # pkg_which <path> * apt / dpkg # dpkg -S <path> * yum / rpm: # rpm -q -f <path> === 未安装 === Google <file name> == 列出某包文件列表 == * pacman: # pacman -Q -l <package name> * ports: # pkg_info -L <package name with package version> # pkg_info -L <package name>-\* // hackish! * apt / dpkg: # dpkg -L <package name> * yum / rpm: # rpm -q -l <package name> == 装 == * pacman: # pacman -S <package name> * ports: # pkg_add -r <package name> # portinstall -PPv <package name> # cd <package path>; make install * apt / dpkg: # apt-get install <package name> * yum / rpm: # yum install <package name> == 删 == * pacman: # pacman -R <package name> * ports: # pkg_delete <package name with version> * apt / dpkg: # apt-get remove <package name> * yum / rpm: # yum remove <package name> 3e4c2385aabdea2cd18bfa1ff466facb05d52a87 85 84 2011-11-18T06:21:29Z HenryHu 1 /* 查询文件属于那个包 */ wikitext text/x-wiki Package Management,也就是包管理 其实常用命令就那几个…… 所以列一下吧 == 根据名字查找包 == * pacman: # pacman -Ss <string> * ports: # psearch <string> * apt / dpkg: # apt-cache search <string> * yum / rpm: # yum search <string> == 查询文件属于哪个包 == === 已安装 === * pacman: # pacman -Q -o <path> * ports: # pkg_info -W <path> # pkg_which <path> * apt / dpkg # dpkg -S <path> * yum / rpm: # rpm -q -f <path> === 未安装 === Google <file name> == 列出某包文件列表 == * pacman: # pacman -Q -l <package name> * ports: # pkg_info -L <package name with package version> # pkg_info -L <package name>-\* // hackish! * apt / dpkg: # dpkg -L <package name> * yum / rpm: # rpm -q -l <package name> == 装 == * pacman: # pacman -S <package name> * ports: # pkg_add -r <package name> # portinstall -PPv <package name> # cd <package path>; make install * apt / dpkg: # apt-get install <package name> * yum / rpm: # yum install <package name> == 删 == * pacman: # pacman -R <package name> * ports: # pkg_delete <package name with version> * apt / dpkg: # apt-get remove <package name> * yum / rpm: # yum remove <package name> 5a8f4d87665ced1fd37fde7bccff83183c76bbbb Upnpsync 0 36 86 2011-12-03T22:56:13Z HenryHu 1 以内容“upnpsync是个小脚本。主要用来同步路由器的UPnP转发信息和Cable Modem的转发信息。 最近在Time Warner的Cable Modem后面搞了个无线路由...”创建新页面 wikitext text/x-wiki upnpsync是个小脚本。主要用来同步路由器的UPnP转发信息和Cable Modem的转发信息。 最近在Time Warner的Cable Modem后面搞了个无线路由。之后又给这个路由刷了dd-wrt。 虽然一切都不错,但是对于要用UPnP进行端口转发的程序来说,因为它只会通过UPnP让路由转发,没有通知Cable Modem,导致它即使设置了端口转发,外网还是无法连接到它监听的端口。 网络结构是: Internet <-> <74.73.xx.xx> [Time Warner Cable Modem] <192.168.0.1> <-> <192.168.0.x> [DLink Wireless Router] <192.168.1.1> <-> <192.168.1.x> [My Computer] Time Warnar那个破Modem居然连配置都没法配,所有配置界面都锁死了,直接filter了23,80端口…… 幸好它居然留着UPnP。端口扫描扫出来5555和8081俩端口,尝试了一下,http://192.168.0.1:5555/ 就是它的UPnP地址…… 于是搞了个小脚本,可以根据无线路由上UPnP的端口转发信息,在Cable Modem上用UPnP自动配好对应的端口转发~ <source lang='perl'> #!/usr/bin/perl sub get_external($) { my ($url) = @_; $_ = `upnpc -u $url -s | grep External`; /ExternalIPAddress = ([0-9\.]+)+/; return $1; } sub get_fwd_list($) { my ($url) = @_; $_ = `upnpc -u $url -l | grep '\\\->'`; foreach $line(split(/\n/)) { if ($line =~ m/\s+(\d+)\s+([A-Za-z]+)\s+(\d+)->([0-9\.]+):(\d+)\s+'(.*)'\s+'(.*)'/) { # print "No.$1 Proto:$2 Ext.Port:$3 LocalIP:$4 LocalPort:$5 Desc:$6 Note:$7\n"; $result[$1] = {"proto"=>$2, "extport"=>$3, "localip"=>$4, "localport"=>$5, "desc"=>$6, "note"=>$7}; } } return @result; } $router_ip = "192.168.1.1"; $modem_ip = "192.168.0.1"; $router_upnp = "http://192.168.1.1:1780/InternetGatewayDevice.xml"; $modem_upnp = "http://192.168.0.1:5555/"; $router_external = get_external($router_upnp); $modem_external = get_external($modem_upnp); @router_fwd = get_fwd_list($router_upnp); @modem_fwd = get_fwd_list($modem_upnp); print "Modem External IP: $modem_external\n"; print "Router External IP: $router_external\n"; foreach $router_pair (@router_fwd) { $proto = $router_pair->{"proto"}; $extport = $router_pair->{"extport"}; $found = 0; $good_pair = ""; print "Router: $proto $router_external:$extport -> $router_pair->{'localip'}:$router_pair->{'localport'}"; foreach $modem_pair (@modem_fwd) { if ($modem_pair->{"proto"} eq $proto and $modem_pair->{"localport"} == $extport) { $found = 1; $good_pair = $modem_pair; if ($modem_pair->{"localip"} ne $router_external) { $modem_local = $modem_pair->{"localip"}; print "\nWarning: Modem forwarding to strange IP: $modem_local\n"; } } } if (not $found) { print "... Not found!\n"; $ret = `upnpc -u $modem_upnp -a $router_external $extport $extport $proto`; if ($? != 0) { print "ERROR adding port forwarding pair!\n"; print $ret; } else { print "Added forwarding $proto $modem_external:$extport->$router_external:$extport\n"; } } else { print "... Found\n"; print "Modem: $good_pair->{'proto'} $modem_external:$good_pair->{'extport'} -> $good_pair->{'localip'}:$good_pair->{'localport'}\n"; } } </source> 这里的router_ip和modem_ip都是对内IP,应该都很清楚。 router_upnp和modem_upnp都是对应设备的UPnP地址。可以通过在计算机与该设备直连的情况下,用upnpc -l发现出来(自动发现还是不太靠谱啊……)。 35b0fd70623a6151d04d66b41c08083218ae6492 87 86 2011-12-03T23:00:03Z HenryHu 1 wikitext text/x-wiki upnpsync是个小脚本。主要用来同步路由器的UPnP转发信息和Cable Modem的转发信息。 最近在Time Warner的Cable Modem后面搞了个无线路由。之后又给这个路由刷了dd-wrt。 虽然一切都不错,但是对于要用UPnP进行端口转发的程序来说,因为它只会通过UPnP让路由转发,没有通知Cable Modem,导致它即使设置了端口转发,外网还是无法连接到它监听的端口。 网络结构是: Internet <-> <74.73.xx.xx> [Time Warner Cable Modem] <192.168.0.1> <-> <192.168.0.x> [DLink Wireless Router] <192.168.1.1> <-> <192.168.1.x> [My Computer] Time Warnar那个破Modem居然连配置都没法配,所有配置界面都锁死了,直接filter了23,80端口…… 幸好它居然留着UPnP。端口扫描扫出来5555和8081俩端口,尝试了一下,http://192.168.0.1:5555/ 就是它的UPnP地址…… 于是搞了个小脚本,可以根据无线路由上UPnP的端口转发信息,在Cable Modem上用UPnP自动配好对应的端口转发~ <source lang='perl'> #!/usr/bin/perl sub get_external($) { my ($url) = @_; $_ = `upnpc -u $url -s | grep External`; /ExternalIPAddress = ([0-9\.]+)+/; return $1; } sub get_fwd_list($) { my ($url) = @_; $_ = `upnpc -u $url -l | grep '\\\->'`; @result = (); foreach $line(split(/\n/)) { if ($line =~ m/\s+(\d+)\s+([A-Za-z]+)\s+(\d+)->([0-9\.]+):(\d+)\s+'(.*)'\s+'(.*)'/) { # print "No.$1 Proto:$2 Ext.Port:$3 LocalIP:$4 LocalPort:$5 Desc:$6 Note:$7\n"; $result[$1] = {"proto"=>$2, "extport"=>$3, "localip"=>$4, "localport"=>$5, "desc"=>$6, "note"=>$7}; } } return @result; } $router_ip = "192.168.1.1"; $modem_ip = "192.168.0.1"; $router_upnp = "http://192.168.1.1:1780/InternetGatewayDevice.xml"; $modem_upnp = "http://192.168.0.1:5555/"; $router_external = get_external($router_upnp); $modem_external = get_external($modem_upnp); @router_fwd = get_fwd_list($router_upnp); @modem_fwd = get_fwd_list($modem_upnp); print "Modem External IP: $modem_external\n"; print "Router External IP: $router_external\n"; foreach $router_pair (@router_fwd) { $proto = $router_pair->{"proto"}; $extport = $router_pair->{"extport"}; $found = 0; $good_pair = ""; print "Router: $proto $router_external:$extport -> $router_pair->{'localip'}:$router_pair->{'localport'}"; foreach $modem_pair (@modem_fwd) { if ($modem_pair->{"proto"} eq $proto and $modem_pair->{"localport"} == $extport) { $found = 1; $good_pair = $modem_pair; if ($modem_pair->{"localip"} ne $router_external) { $modem_local = $modem_pair->{"localip"}; print "\nWarning: Modem forwarding to strange IP: $modem_local\n"; } } } if (not $found) { print "... Not found!\n"; $ret = `upnpc -u $modem_upnp -a $router_external $extport $extport $proto`; if ($? != 0) { print "ERROR adding port forwarding pair!\n"; print $ret; } else { print "Added forwarding $proto $modem_external:$extport->$router_external:$extport\n"; } } else { print "... Found\n"; print "Modem: $good_pair->{'proto'} $modem_external:$good_pair->{'extport'} -> $good_pair->{'localip'}:$good_pair->{'localport'}\n"; } } </source> 这里的router_ip和modem_ip都是对内IP,应该都很清楚。 router_upnp和modem_upnp都是对应设备的UPnP地址。可以通过在计算机与该设备直连的情况下,用upnpc -l发现出来(自动发现还是不太靠谱啊……)。 254d1baf6ae890125f5a519101b6ee09e7a29049 88 87 2011-12-04T00:02:52Z HenryHu 1 wikitext text/x-wiki upnpsync是个小脚本。主要用来同步路由器的UPnP转发信息和Cable Modem的转发信息。 最近在Time Warner的Cable Modem后面搞了个无线路由。之后又给这个路由刷了dd-wrt。 虽然一切都不错,但是对于要用UPnP进行端口转发的程序来说,因为它只会通过UPnP让路由转发,没有通知Cable Modem,导致它即使设置了端口转发,外网还是无法连接到它监听的端口。 网络结构是: Internet <-> <74.73.xx.xx> [Time Warner Cable Modem] <192.168.0.1> <-> <192.168.0.x> [DLink Wireless Router] <192.168.1.1> <-> <192.168.1.x> [My Computer] Time Warnar那个破Modem居然连配置都没法配,所有配置界面都锁死了,直接filter了23,80端口…… 幸好它居然留着UPnP。端口扫描扫出来5555和8081俩端口,尝试了一下,http://192.168.0.1:5555/ 就是它的UPnP地址…… 于是搞了个小脚本,可以根据无线路由上UPnP的端口转发信息,在Cable Modem上用UPnP自动配好对应的端口转发~ <source lang='perl'> #!/usr/bin/perl sub get_external($) { my ($url) = @_; $_ = `upnpc -u $url -s | grep External`; /ExternalIPAddress = ([0-9\.]+)+/; return $1; } sub get_fwd_list($) { my ($url) = @_; $_ = `upnpc -u $url -l | grep '\\\->'`; @result = (); foreach $line(split(/\n/)) { if ($line =~ m/\s*(\d+)\s+([A-Za-z]+)\s+(\d+)->([0-9\.]+):(\d+)\s+'(.*)'\s+'(.*)'/) { # print "No.$1 Proto:$2 Ext.Port:$3 LocalIP:$4 LocalPort:$5 Desc:$6 Note:$7\n"; $result[$1] = {"proto"=>$2, "extport"=>$3, "localip"=>$4, "localport"=>$5, "desc"=>$6, "note"=>$7}; } } return @result; } $router_ip = "192.168.1.1"; $modem_ip = "192.168.0.1"; $router_upnp = "http://192.168.1.1:1780/InternetGatewayDevice.xml"; $modem_upnp = "http://192.168.0.1:5555/"; $router_external = get_external($router_upnp); $modem_external = get_external($modem_upnp); @router_fwd = get_fwd_list($router_upnp); @modem_fwd = get_fwd_list($modem_upnp); print "Modem External IP: $modem_external\n"; print "Router External IP: $router_external\n"; foreach $router_pair (@router_fwd) { $proto = $router_pair->{"proto"}; $extport = $router_pair->{"extport"}; $found = 0; $good_pair = ""; print "Router: $proto $router_external:$extport -> $router_pair->{'localip'}:$router_pair->{'localport'}"; foreach $modem_pair (@modem_fwd) { if ($modem_pair->{"proto"} eq $proto and $modem_pair->{"localport"} == $extport) { $found = 1; $good_pair = $modem_pair; if ($modem_pair->{"localip"} ne $router_external) { $modem_local = $modem_pair->{"localip"}; print "\nWarning: Modem forwarding to strange IP: $modem_local\n"; } } } if (not $found) { print "... Not found!\n"; $ret = `upnpc -u $modem_upnp -a $router_external $extport $extport $proto`; if ($? != 0) { print "ERROR adding port forwarding pair!\n"; print $ret; } else { print "Added forwarding $proto $modem_external:$extport->$router_external:$extport\n"; } } else { print "... Found\n"; print "Modem: $good_pair->{'proto'} $modem_external:$good_pair->{'extport'} -> $good_pair->{'localip'}:$good_pair->{'localport'}\n"; } } </source> 这里的router_ip和modem_ip都是对内IP,应该都很清楚。 router_upnp和modem_upnp都是对应设备的UPnP地址。可以通过在计算机与该设备直连的情况下,用upnpc -l发现出来(自动发现还是不太靠谱啊……)。 0e5cf9c6fa4a9b8d59b703c25ac4464b0869af54 89 88 2011-12-04T06:07:25Z HenryHu 1 wikitext text/x-wiki [[Category:脚本]] upnpsync是个小脚本。主要用来同步路由器的UPnP转发信息和Cable Modem的转发信息。 最近在Time Warner的Cable Modem后面搞了个无线路由。之后又给这个路由刷了dd-wrt。 虽然一切都不错,但是对于要用UPnP进行端口转发的程序来说,因为它只会通过UPnP让路由转发,没有通知Cable Modem,导致它即使设置了端口转发,外网还是无法连接到它监听的端口。 网络结构是: Internet <-> <74.73.xx.xx> [Time Warner Cable Modem] <192.168.0.1> <-> <192.168.0.x> [DLink Wireless Router] <192.168.1.1> <-> <192.168.1.x> [My Computer] Time Warnar那个破Modem居然连配置都没法配,所有配置界面都锁死了,直接filter了23,80端口…… 幸好它居然留着UPnP。端口扫描扫出来5555和8081俩端口,尝试了一下,http://192.168.0.1:5555/ 就是它的UPnP地址…… 于是搞了个小脚本,可以根据无线路由上UPnP的端口转发信息,在Cable Modem上用UPnP自动配好对应的端口转发~ <source lang='perl'> #!/usr/bin/perl sub get_external($) { my ($url) = @_; $_ = `upnpc -u $url -s | grep External`; /ExternalIPAddress = ([0-9\.]+)+/; return $1; } sub get_fwd_list($) { my ($url) = @_; $_ = `upnpc -u $url -l | grep '\\\->'`; @result = (); foreach $line(split(/\n/)) { if ($line =~ m/\s*(\d+)\s+([A-Za-z]+)\s+(\d+)->([0-9\.]+):(\d+)\s+'(.*)'\s+'(.*)'/) { # print "No.$1 Proto:$2 Ext.Port:$3 LocalIP:$4 LocalPort:$5 Desc:$6 Note:$7\n"; $result[$1] = {"proto"=>$2, "extport"=>$3, "localip"=>$4, "localport"=>$5, "desc"=>$6, "note"=>$7}; } } return @result; } $router_ip = "192.168.1.1"; $modem_ip = "192.168.0.1"; $router_upnp = "http://192.168.1.1:1780/InternetGatewayDevice.xml"; $modem_upnp = "http://192.168.0.1:5555/"; $router_external = get_external($router_upnp); $modem_external = get_external($modem_upnp); @router_fwd = get_fwd_list($router_upnp); @modem_fwd = get_fwd_list($modem_upnp); print "Modem External IP: $modem_external\n"; print "Router External IP: $router_external\n"; foreach $router_pair (@router_fwd) { $proto = $router_pair->{"proto"}; $extport = $router_pair->{"extport"}; $found = 0; $good_pair = ""; print "Router: $proto $router_external:$extport -> $router_pair->{'localip'}:$router_pair->{'localport'}"; foreach $modem_pair (@modem_fwd) { if ($modem_pair->{"proto"} eq $proto and $modem_pair->{"localport"} == $extport) { $found = 1; $good_pair = $modem_pair; if ($modem_pair->{"localip"} ne $router_external) { $modem_local = $modem_pair->{"localip"}; print "\nWarning: Modem forwarding to strange IP: $modem_local\n"; } } } if (not $found) { print "... Not found!\n"; $ret = `upnpc -u $modem_upnp -a $router_external $extport $extport $proto`; if ($? != 0) { print "ERROR adding port forwarding pair!\n"; print $ret; } else { print "Added forwarding $proto $modem_external:$extport->$router_external:$extport\n"; } } else { print "... Found\n"; print "Modem: $good_pair->{'proto'} $modem_external:$good_pair->{'extport'} -> $good_pair->{'localip'}:$good_pair->{'localport'}\n"; } } </source> 这里的router_ip和modem_ip都是对内IP,应该都很清楚。 router_upnp和modem_upnp都是对应设备的UPnP地址。可以通过在计算机与该设备直连的情况下,用upnpc -l发现出来(自动发现还是不太靠谱啊……)。 95586f9169245dee3e675d178960d1af3c32b1c8 90 89 2011-12-04T21:36:49Z HenryHu 1 wikitext text/x-wiki [[Category:脚本]] upnpsync是个小脚本。主要用来同步路由器的UPnP转发信息和Cable Modem的转发信息。 最近在Time Warner的Cable Modem后面搞了个无线路由。之后又给这个路由刷了dd-wrt。 虽然一切都不错,但是对于要用UPnP进行端口转发的程序来说,因为它只会通过UPnP让路由转发,没有通知Cable Modem,导致它即使设置了端口转发,外网还是无法连接到它监听的端口。 网络结构是: Internet <-> <74.73.xx.xx> [Time Warner Cable Modem] <192.168.0.1> <-> <192.168.0.x> [DLink Wireless Router] <192.168.1.1> <-> <192.168.1.x> [My Computer] Time Warnar那个破Modem居然连配置都没法配,所有配置界面都锁死了,直接filter了23,80端口…… 幸好它居然留着UPnP。端口扫描扫出来5555和8081俩端口,尝试了一下,http://192.168.0.1:5555/ 就是它的UPnP地址…… 于是搞了个小脚本,可以根据无线路由上UPnP的端口转发信息,在Cable Modem上用UPnP自动配好对应的端口转发~ 后来又加了个小功能,会自动把在本地找不到的Modem上的转发信息干掉,这样在程序结束后能自动清理。 <source lang='perl'> #!/usr/bin/perl sub get_external($) { my ($url) = @_; $_ = `/usr/local/bin/upnpc -u $url -s | grep External`; /ExternalIPAddress = ([0-9\.]+)+/; return $1; } sub get_fwd_list($) { my ($url) = @_; $_ = `/usr/local/bin/upnpc -u $url -l | grep '\\\->'`; @result = (); foreach $line(split(/\n/)) { if ($line =~ m/\s*(\d+)\s+([A-Za-z]+)\s+(\d+)->([0-9\.]+):(\d+)\s+'(.*)'\s+'(.*)'/) { # print "No.$1 Proto:$2 Ext.Port:$3 LocalIP:$4 LocalPort:$5 Desc:$6 Note:$7\n"; $result[$1] = {"proto"=>$2, "extport"=>$3, "localip"=>$4, "localport"=>$5, "desc"=>$6, "note"=>$7}; } } return @result; } $router_ip = "192.168.1.1"; $modem_ip = "192.168.0.1"; $router_upnp = "http://192.168.1.1:1780/InternetGatewayDevice.xml"; $modem_upnp = "http://192.168.0.1:5555/"; $router_external = get_external($router_upnp); $modem_external = get_external($modem_upnp); @router_fwd = get_fwd_list($router_upnp); @modem_fwd = get_fwd_list($modem_upnp); print "Modem External IP: $modem_external\n"; print "Router External IP: $router_external\n"; foreach $router_pair (@router_fwd) { $proto = $router_pair->{"proto"}; $extport = $router_pair->{"extport"}; $found = 0; $good_pair = ""; print "Router: $proto $router_external:$extport -> $router_pair->{'localip'}:$router_pair->{'localport'}"; foreach $modem_pair (@modem_fwd) { if ($modem_pair->{"proto"} eq $proto and $modem_pair->{"localport"} == $extport) { $found = 1; $good_pair = $modem_pair; $modem_pair->{"router_pair"} = $router_pair; if ($modem_pair->{"localip"} ne $router_external) { $modem_local = $modem_pair->{"localip"}; print "\nWarning: Modem forwarding to strange IP: $modem_local\n"; } } } if (not $found) { print "... Not found!\n"; $ret = `/usr/local/bin/upnpc -u $modem_upnp -a $router_external $extport $extport $proto`; if ($? != 0) { print "ERROR adding port forwarding pair!\n"; print $ret; } else { print "Added forwarding $proto $modem_external:$extport->$router_external:$extport\n"; } } else { print "... Found\n"; print "Modem: $good_pair->{'proto'} $modem_external:$good_pair->{'extport'} -> $good_pair->{'localip'}:$good_pair->{'localport'}\n"; } } foreach $modem_pair (@modem_fwd) { if (not $modem_pair->{"router_pair"}) { $proto = $modem_pair->{'proto'}; $extport = $modem_pair->{'extport'}; print "Found extra modem pair: $proto $modem_external:$extport -> $modem_pair->{'localip'}:$modem_pair->{'localport'}\n"; $ret = `/usr/local/bin/upnpc -u $modem_upnp -d $extport $proto`; if ($? != 0) { print "ERROR deleting modem pair!\n"; print $ret; } else { print "Extra pair deleted.\n"; } } } </source> 这里的router_ip和modem_ip都是对内IP,应该都很清楚。 router_upnp和modem_upnp都是对应设备的UPnP地址。可以通过在计算机与该设备直连的情况下,用upnpc -l发现出来(自动发现还是不太靠谱啊……)。 6dd8a0b5c7c7fde3e7d8e5adf628493963defd71 首页 0 1 91 33 2011-12-04T21:46:57Z HenryHu 1 wikitext text/x-wiki [[SubsConscious]] [[:Category:脚本|Scripts]] == 入门 == * [http://www.mediawiki.org/wiki/Manual:Configuration_settings MediaWiki 配置设置列表] * [http://www.mediawiki.org/wiki/Manual:FAQ/zh-hans MediaWiki常见问题] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki发布邮件列表] d9da9b506e54460aedaea0cceccf4406091ac4f7 97 91 2011-12-15T00:55:40Z HenryHu 1 wikitext text/x-wiki [[SubsConscious]] [[:Category:脚本|Scripts]] [[Package Management]] == 入门 == * [http://www.mediawiki.org/wiki/Manual:Configuration_settings MediaWiki 配置设置列表] * [http://www.mediawiki.org/wiki/Manual:FAQ/zh-hans MediaWiki常见问题] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki发布邮件列表] 4ebda05be2fc2beba4412f6e02e0eb53b324d69f 穿越悲剧 0 37 92 2011-12-08T01:49:55Z HenryHu 1 以内容“http://www.acfun.tv/v/ac269911/ ACG穿越悲剧 主页>文章> 2011-12-06 22:08:32 杀戮无限 投稿 1某女穿越后,发现自己手握一把重型连续狙...”创建新页面 wikitext text/x-wiki http://www.acfun.tv/v/ac269911/ ACG穿越悲剧 主页>文章> 2011-12-06 22:08:32 杀戮无限 投稿 1某女穿越后,发现自己手握一把重型连续狙击枪端坐于大楼顶上,回想脑中无数战斗技巧 ,于是聚精会神瞄准目标那个白发瘦弱青年连开数枪…… 2某男穿越后,发现自己变成了一个可爱小正太,对面一个蓝衣白甲的美丽女剑士,周围无 数恐怖的触手怪,不由向前扑进女剑士的怀里…… 3无意中登上一座客船,只见前面有一带眼镜小孩携一高中女生走来.略一思索大骇,转身欲走 却见到后面走来个绑马尾的高中生... 4某男穿越后,发觉自己正拉着美丽学姐的手冲出一栋富丽堂皇的别墅,这是学姐问了一句 “她们呢?她们都到哪里去了?”不由自主的回答“都死了,大家都死了…… 5某恨嫁宅女一日穿越到二次元,发现自己成了萌死人的合法loli,无数宅男心中的女神。 且有一夫君,情投意合,恩爱无边。怀中还抱着可爱的女儿,不禁感叹终于成了人生的赢家 。这时夫君缓缓开口:“我们的女儿,就取名叫此方吧。” 6某宅男醒来发现自己成了威猛兄贵,并且有13条命,身旁还有可爱白发loli陪伴,正要大 展宏图发现一男一女向他走来·· 7某男醒来发现自己竟是一名王子,风度翩翩,坐在宝座上,只是宫殿一片漆黑,前面一个 士兵走过了把头盔摘下来扔到地上说,好久不见了呢,哥哥。 8一宅男穿越后发现本是衰弱的身体变得强大有力,正想暴走发泄一番时,忽然脱口而出道 :“吾之一生!无怨无悔!” 9某游戏王爱好者穿越过后发现自己站在火车上,自己占有绝对的优势,正欲大喜.对面突然说 了句 "发动速攻魔法 狂战士之魂........." 10某宅男穿越,发现自己变成了娇俏可怜的小萝莉,记忆中还有个体贴爱护自己的孪生姐姐 ,也算是身出名门的悠久魔法师,正在窃喜之际一个苍老的男人领着另一个小男孩过来。 “樱,这是你的哥哥慎二,过来问好。” 11某宅穿越发见变成了某高科技基地的女秘书,在基地走着走着突然发现前面冲过来一堆神 色紧张的特种兵+自己的上司,回头一看一个粉红色头发戴了个全封闭头盔的裸体女人在向自 己一步步走过来..... 12某宅穿越,发现自己为一王牌狙击手,刚刚把自己的徒弟一枪撂倒,看着下面的十字疤男 和银发小姑娘不禁脱口而出“就算是垂死挣扎也有点太过分了吧。” 13某宅穿越,发现自己成为一名政府秘密组织老大,身形魁梧,精通体术,更兼有勇有谋, 手下小弟个个精干。眼前红发矮子强则强矣,然被己连番计策攻心,五感去其四,流血过多 ,多处骨折。自己占据天时地利人和不败之境,只差上前一刀来个干脆………… 14某人穿越,发现自己身处豪宅之中。细一思索,发觉自己精通箭术,出身自魔术师世家, 家族虽败但万事具备,还有一名身材高佻气质御姐全听使唤。正欲一展全脚,突见眼前出现 一个紫发少女说,“哥哥,对不起”…… 15某男穿越,发现自己被钓空中,面前一猥琐恶汉坐在椅子上,身边有4个好像是基佬的家伙 16某宅男穿越,发现自己变成一只白色九尾大妖,是人挡杀人佛挡杀佛,普天之下再无敌手 。心中正暗喜之际,突见面前有一人一妖,那人一手指天曰:“太阳正和我们并肩作战。 17某宅男穿越后发现自己虽然变了女生,可是战斗力却是全大陆最强,用10%的力量就能把 排名仅次于自己的三个同伴打得抬不起头。这时,自己眼前跪着的美少女突然楚楚可怜地说 ,“求求你,给我一个机会…… 18某废柴穿越,发现自己成进化顶点的终极生物。不老不死,威力无穷,是上一切对于自己 斗不过是食物虫蚁而已。 正当暗爽的时候,发现脚下地面开始震动,一个重伤的人类小子对自己坏笑…… 19某男一睁眼醒来,想起自己是政府特殊作战部队的精英,可靠的队友里既有后方做情报支 援的萌妹子,还有和自己拥有同样灵能力的摩托车打女。 正要举起手里的饮料为构建和谐后宫而干杯的时候,突然发现有蝴蝶飞过。 20某日穿越,发现自己成了一宇宙舰队的指挥官,统领数百万舰队,0机动兵器更是无量大 数,在一个边境小星球附近遭遇了有数万年积怨的敌对民族的一支部队,相互间正摆开阵式 准备大干一场,突然耳边响起悦耳的歌声 21某死弱宅穿越,发现自己身为某一高中橄榄球队队长,马上即将与另一高中的娘泡球队展 开一场“毫i无意义”的友谊赛,听说对方为了这场比赛进行了一个周的“毫无意义”的特 训。天下着雨,对方身着绿色军服入场!? 22某宅穿越后发现自己变成一貌美正太,边上有个双胞胎loli姐姐。姐弟两一直相依为命, 虽然看似身材柔弱却有一副好身手,而且喜欢玩虐杀和换装的变态游戏。 在一次受命暗杀黑社会人物后被该组织追杀,途中姐姐惨遭不幸自己也快要不行的时候得到 一位热心肠的大哥哥和他朋友的逃亡保护,一路上被大哥哥的温柔所治愈忍不住在大哥哥面 前自爆了一把却遭到了大哥哥朋友的嫉妒。不过所幸最终九死一生安全逃出了组织的追捕, 和大哥哥许下约定跳下了船。 虽然发生了很多事,不过从今以后应该可以过上新生活吧。远处给自己安排新身份的接头人 正在走来,今天的天空可真蓝呀。。。 23某肥宅穿越,发现自己还是一个死胖子。细细想来,自己是当地首屈一指的奴隶贩子,玩 过无数萝莉御姐。虽无称霸的实力,但淫乐一世不在话下。身边群芳环伺,心想破了处再说 ,发现座下走过来一个不起眼的矮子,开口就是:“我给你介绍一个好女人。” 24某人一觉醒来,发现自己成了白发美红眼少年,得意之余跑到湖边的残破雕像上唱欢乐颂 ,唱着唱着发现一漂亮的黑发男孩在旁边一脸羞涩地看着自己…… 25某宅男一觉醒来,发现自己无比英俊帅气,银发飘飘,手拿太刀正宗,举手投足毁天灭地 ,纵横捭阖,正欲狂笑,忽见对面一金发小帅哥,手持组合大剑直冲而来,大吼道:“六式 超究武神霸斩!” 26某穿越,自觉魔力无限,法力无边。身边还有一超时代杀人木偶伺候。虽然身高似乎略矮 ,但对于10岁的年龄来说这完全不是问题。就在得意之时,发现对面有一红发男子正左手拿 小抄,右手掏大蒜...耶?为何有大蒜? 27某被发卡无数次宅男一觉醒来,发现自己坐在一张轮椅上,正在欣赏美丽夕阳,身后有一 白色长发超级大美女陪同,略一思索,想起她是自己老婆。正想着晚上回去后可以干什么不 河蟹的事儿,然后突然眼皮一重,太阳落山了。 28一眼镜宅男穿越,清醒后发现自身身材匀称,面貌俊秀,视力破表,身穿一套可飞行的单 兵作战护甲。忽然发现面前站着一位半裸的LOLI,正泫然欲泣的看着他。本想拿棒棒糖喂食 她,结果LOLI转身就跑掉了,远远传来句“怕死谈什么恋爱啊!” 29某宅穿越,发现自己变成一个小loli,身体好像还是木头做的,左眼还带了个眼罩,再仔 细一看还有个红衣金发马尾loli骑在自己身上欲对自己下毒手,心中不禁有点惊慌。还好这 时旁边小正太喊了一句“住手”,红衣loli露出了一个破绽,于是为了保住自己的性命,某 宅毫不犹豫的就用右手的水晶剑下了毒手,红衣loli倒地,从她身上飞出3个红色光球飞入 自己体内。。。。。。 30某宅穿越后发现自己英俊潇洒一表人才,不仅有科技成就搞政治也是一流。此时更是已经 一统卫星地球,号令数万大军,手下还有人挡杀人佛挡杀佛的两位顶尖打手。正要在要塞里 喝咖啡时一粉红战舰从远处冒出。。 31某人穿越,发觉自己武功天下无敌,两个宿敌已经被自己打至奄奄一息,更有其中之一把一 股"世人梦寐以求的力量"送进自己体里,大喜之际,发觉自己已经身怀三颗龙元的力量 ...... 32某人穿越发现自己身材巨大力量无比 乃守护宇宙和平的光之巨人是也 刚想大展拳脚找找 怪兽晦气 只听见一声"杰~顿..." 33某人穿越发现自己威严健硕身负神力 正变化巨大以雷电之力将一白皮红纹的凶暴光头逼 入绝境 欲痛下杀手时只见那光头将手中兵刃往地下一插大吼一声:"宙斯你赢了!!给老子个 痛快吧!!" 34某人穿越,发现自己成为一拉面师傅。身怀绝技,妹子无数:三无、天然呆、声优...最 终以拉面决胜,抱得美人归,在众人的祝福中开始了新婚旅行 35某废柴一事无成大叔一觉醒来,发现自己身为大制药公司的部长并与社长关系甚好,且有 房有车有娇妻,平时没事骚扰一下女下属开个房打打炮,还有个青春漂亮的女儿,俨然一人 生赢家。虽然面前这个客户一脸刁钻样子给自己脸色看,但自己真是命有贵人,一更长相猥 琐的大叔自称公司员工三下五除二就替自己解决了难题。咦,只是他没事干嘛披条黄毛巾… … 36某宅穿越,发现自己正在干着一个穿着礼园女学院校服的美少女,虽然美少女看似目无表 情毫不在意,但是自己能干上美少女不由得还是内心暗喜,正欲换个姿势继续干的时候,发 现自己右手上拿着小刀.... 37某宅穿越,发觉自己是意气风发的棒球队成员,刚刚开始独居的新生活甲子园有望而且和 隔壁的妹子进展顺利。回到家忽然发现自己的行李都被打开了,而且房间中央坐着个不认识 的穿着自己衣服长发马尾男问:你是谁? 38某日穿越,发觉自己为世上最强者,武功天下第一,手下能人无数,军队所过之处无不摧 枯拉朽,周边诸强不是投降归附就是苟延残喘,整个世界已经在自己手中,正待大展拳脚, 眼前出现一个胸前有7个伤疤的男人 39某宅男一觉醒来,发现自己穿越成白种人,英俊潇洒风流倜傥,正在驾驶一辆小型货车, 车上是价值几十亿美刀的贵重物品,现在只要这批货出手,房子美女什么的都是唾手可得。 志得意满间,前方忽然跳出一黑人和一泥轰人,嘴里大喊着什么 40某病弱穿越变成特种部队成员,立时接到解决豪华宾馆里一男一女两个恐怖分子的任务。 跟队友摸索至门口,一马当先一脚踹开门,见男子立于窗前,扣动扳机突突突把其打成筛子 。 以为任务结束了,抬头看见月亮变成血红色… 41你穿越了,醒了之后发现你拿枪顶着一个白发少年,那少年正猥琐地抚摸着一名少女,少 年扭曲着脸看着你大喊:"只要给本大爷一秒钟……" 42你穿越成了一个全球超强的存在,本体在月球,并且可以吸收地球增强自己的实力 突然 你听到你体内传来了一句:我们的手鲜红如火,它叫我紧抓胜利 43你穿越成了地球意志,拥有绝强的力量,你的面前有3个臭虫一样的存在,突然,两个臭 虫手上分别燃起了红色和苍蓝的火焰,另外一个臭虫手指上冒出了白光 44你穿越成了一个美少女,你发现自己没有痛觉,突然,一伙流氓向你走了过来… 45你穿越了,你发现自己好像神一样,所有说出口的话都成真了,正在你兴奋的时候,你的 眼角瞥到身后角落里有个晕倒的修女…… 46你穿越成了一个绝对强大的存在,全球能和你媲美的不超过18人 然后 你还有一个可爱的 好朋友 你们连衣服都一样的 然后 你还会驾驶机器人 然后 你被你朋友捏住了 47你穿越了,你发现自己是个几乎完美的男人,还有个漂亮的女朋友。这时候,一个男生闯 进了你的教室一把拉住你女朋友让她赶紧跟他走。。。。 48你穿越了,发现你成了个女生,前去探望车祸后性格大变的暗恋对象,然后你推门进去, 发现墙壁周围都是乱七八糟的颜色…… 49你穿越了,变成了一个美女,一天你发现你暗恋的上司死了,你很悲伤,然后去看,发现 上司没死,正当你惊喜地靠近他时,他说:“崇拜,是人和人之间最远的距离……” 50某男穿越后,发现正趴在一个女人身上运动。观察下四周,好像是个地下室吧,周围还有 一群穿着斗篷蒙面人,看下自己身上衣服,应该是自己人,地面上还有一个魔法阵。是要举 行什么仪式吗?马上整理这具身体的记忆,原来身下这个叫北见什么的女人是祭品啊。那么 不管了,先爽了再说! 51某男穿越后发现自己怀抱古典美女,斜倚一残破大楼的阳台边。虽然深受重伤但是战斗已 经结束,并有一强壮但妖媚的男子眼含热泪望着自己。 好一番苦战之后的激情四射,哈哈,虽然不知道是什么地方什么故事,但怀中抱妹又有小弟 的男人必然是主角啊。兴奋中,他颤抖着手抽了一根烟。。。。。 52你两眼一黑,发现穿越成了一个国王,你统治着当时最强盛的联盟,你的儿子刚刚打败了 入侵者正要向你回来报告,在你的面前跪着一名穿着黑甲拿着冒着寒气的巨剑的男子.然后 你会说:你要干什么,我的孩子 53你穿越了,发现很有妹子,这天妹子去你家烧水,你接了个短信…… 54你穿越成了一个杰出新人类,正在和4个同伴抢机体。。你的目标是蓝白条的 55你穿越成了一个优秀的杰刚驾驶员 你拥有无比风骚的微操和无比优秀的意识 你接到上级 命令去威吓一下路过的货船 然后远远的看到了一抹绿色…… 56你穿越成一个特种兵,你忽然发现队伍里有个人被铐着手铐,身后还有几个黄种人,其中 一个人的脸上有疤痕………… 57你穿越成了一个帅气的青年,拥有一身绝世的拳法,身边还有你心爱的人,手下有一帮强 悍的部下,你突然看到一个胸口有七个伤疤的男人向你走来,他说:为了战胜你,我从地狱 回来了! 58你穿越为了一位真祖吸血鬼……魔力无边,手下无数,还有座城堡,某天一个自称是你儿 子的帅气半吸血鬼来找你 59你穿越成了一个富家少爷,拥有全球最热门的游戏的开发权和经营权,你看到一个刺猬头 少年对你说:来决斗吧,就用黑暗游戏! 60你穿越成了宇宙最强的存在,可以轻松的毁灭一个星球,当你想大展宏图 征服全宇宙时 ,一个有尾巴的半裸男子对你说:我真的生气了! 61你穿越成了一个镇子黑道的最高统领,你拥有无双的拳法和无比厚实的基础,还有一个天 才哥哥,当你在你家楼顶俯瞰你的势力时,一个红白衣帽的男子向你走来 62你穿越成了世界最强的魔法师,伸手就可以触及本源,拥有着整个世界。突然,一个男人 闯进你的宫殿大喊:“造物主,我来了!“ 63你穿越了,你是龙族,你很骄傲,一天一个绿色的老人唤醒了你,向你要求永保青春 64你穿越成了英雄,拥有斩杀巨龙的实力,你还有一个美丽的LOLI相伴,你下定决心要永远 保护她,对面走来一个金发赤眼的疯子,嘴里老是说什么,杂种啊,本王什么的 65你穿越了,睁眼看见了一个穿着工作服的好男人坐在长椅上对你说道:“亚拉那一卡?” 66你穿越了,发现这辈子是一个用枪的风骚男,枪法无敌,面前一个被绑住的双马尾美女, 身后一个神父笑着对你说:“那么,自杀吧!” 67你穿越成了一个男孩,忽然,一个拿着柴刀的漂亮女孩大喊:嘘DA!向你冲过来……… 68你穿越成为了一个美丽的吸血鬼,你很天才的将吸血鬼血统压制住了,就免去了吸血的冲 动 这时候,你家门铃响了,一个穿着蓝色校服的男生站你家门口 69你穿越了,穿越成一个巨人,你发现你的右手被一个女孩抓住,你刚出左拳去打她,但是 有个刺猬头正右手举拳向你冲来………… 70你穿越了,发现自己成了大魔王,绑架了公主,每天过得很潇洒,但是你刚想享受的时候 ,一个管道工走了过来,躲开你的火焰禁咒,跳到你身后的开关上…… 71你穿越成了一个暴走族,你发现自己正骑着摩托在校园里耀武扬威。突然,面前走来一个 银色头发的美少女。。。 72你穿越成了人行界面,此时你的手正在一个无口LOLI的手中,而你另一只手深深的插入对 方。 73你正在大街上闲步走着,忽然发现一个身穿黑色衣服的兜帽男快速的向你冲来,他一把把 你抓起然后举起右手握拳………… 74你穿越了,你发现自己超强,你的好朋友问你 そんな装备で大丈夫か?你习惯性的回答 了一句:大丈夫だ、问题ない! 75你穿越了,发现自己强大无比,可四周一片混沌。这时候,你的右手摸到一把斧子…… 76你穿越了 成为了一个国家元首的儿子,你拥有无敌的军队 你还是舰长,你还有一个无 比能干的下属 你的下属很聪明的发现了敌人的包围圈 然后通知你 你果断逃跑 突然 你的 下方出现了一艘白色的巨大战舰 77你穿越了,发现你是一个很大的恐怖组织的老板,手下忠心,办事得力,唯一的缺陷就是 你身材比较短小…… 78你穿越了,发现你是一个年少有为的驾驶员的好朋友。他有两个妹子一个活泼过度,一个 无口 79你穿越成了一个异兽。。。有强大的电气能力。。。一天。。一个该死的老头用球型道具 抓了你。。。 80你和一群人一起快乐的旅游,你当时开玩笑,说你的特技是变成食物。 然后遇到大雪,你发现他们用让人蛋疼的目光看着你…… 距离终点还有4天…… 81你穿越了,你发现自己是全球最强的人的师傅,你还拥有超级再生的能力和超强的高达, 然后 你徒弟找上门来了 82你穿越成了一个不死身美御姐。。。。某天你接到一个少年的委托和他潜入一个地方。。 。中途由于臀部曲线太完美被扫描发现了 83你穿越了,你发现自己是个头脑超好的侦探,你追踪一个罪犯已经到了最后一步了,马上 你就能够抓住罪犯了 然后 你的心脏抽了一下 84你穿越了,发现你被70码了之后身边的人都成了怪物 85你穿越了,发现自己是月球之主,你听说地球上很热闹就找了个望远镜,你看到了一个老 头爆了衫双手合拢对着你的方向摆了个造型,旁边还有只大猩猩…… 86你穿越了,发现你和某王女有私情,正当你窃喜时,王女派人来要当时的定情物,你被人 爆了菊花,你临死前把戒指递给了面前的人…… 87你穿越了,发觉自己十分英俊,在学校也很有地位和人气,还有一个很可爱的妹妹,只是 你手中拿着一本伪臣之书。。。 88你穿越了,你发现地面有个披萨盒子,里面还有半块披萨饼,还有一只手想拿披萨,你忽 然很脑抽的踩了披萨一脚………… 89你穿越了,你发现你是一个很厉害的忍者,教授出了一对强者父子。现在你正和你的徒弟 对峙,你召唤出了一只蛤蟆…… 90你穿越了,发觉自己是某个组织的大头目,而二头目小妹妹正和你在某间密闭的室内,这 时有个有胡须的金发男孩走了进来。。。 91你穿越了,发现你是一个后宫男的好朋友,一天,后宫男的正宫说请你吃她母亲做的面包 ,还有母亲认识的一个阿姨做的果酱…… · ebbc9366a148b6a0f1a94ba6a7453dbdbe29373e 93 92 2011-12-08T02:27:34Z HenryHu 1 wikitext text/x-wiki http://www.acfun.tv/v/ac269911/ ACG穿越悲剧 主页>文章> 2011-12-06 22:08:32 杀戮无限 投稿 1某女穿越后,发现自己手握一把重型连续狙击枪端坐于大楼顶上,回想脑中无数战斗技巧 ,于是聚精会神瞄准目标那个白发瘦弱青年连开数枪…… Index 一方? 2某男穿越后,发现自己变成了一个可爱小正太,对面一个蓝衣白甲的美丽女剑士,周围无 数恐怖的触手怪,不由向前扑进女剑士的怀里…… Fate/Zero 3无意中登上一座客船,只见前面有一带眼镜小孩携一高中女生走来.略一思索大骇,转身欲走 却见到后面走来个绑马尾的高中生... Conan 4某男穿越后,发觉自己正拉着美丽学姐的手冲出一栋富丽堂皇的别墅,这是学姐问了一句 “她们呢?她们都到哪里去了?”不由自主的回答“都死了,大家都死了…… 5某恨嫁宅女一日穿越到二次元,发现自己成了萌死人的合法loli,无数宅男心中的女神。 且有一夫君,情投意合,恩爱无边。怀中还抱着可爱的女儿,不禁感叹终于成了人生的赢家 。这时夫君缓缓开口:“我们的女儿,就取名叫此方吧。” <Lucky Star> 泉彼方 此方她妈 6某宅男醒来发现自己成了威猛兄贵,并且有13条命,身旁还有可爱白发loli陪伴,正要大 展宏图发现一男一女向他走来·· Fate/Stay Night Berserke 7某男醒来发现自己竟是一名王子,风度翩翩,坐在宝座上,只是宫殿一片漆黑,前面一个 士兵走过了把头盔摘下来扔到地上说,好久不见了呢,哥哥。 Code Geass 8一宅男穿越后发现本是衰弱的身体变得强大有力,正想暴走发泄一番时,忽然脱口而出道 :“吾之一生!无怨无悔!” <拉奥> 9某游戏王爱好者穿越过后发现自己站在火车上,自己占有绝对的优势,正欲大喜.对面突然说 了句 "发动速攻魔法 狂战士之魂........." 游戏王 10某宅男穿越,发现自己变成了娇俏可怜的小萝莉,记忆中还有个体贴爱护自己的孪生姐姐 ,也算是身出名门的悠久魔法师,正在窃喜之际一个苍老的男人领着另一个小男孩过来。 “樱,这是你的哥哥慎二,过来问好。” <Fate> 11某宅穿越发见变成了某高科技基地的女秘书,在基地走着走着突然发现前面冲过来一堆神 色紧张的特种兵+自己的上司,回头一看一个粉红色头发戴了个全封闭头盔的裸体女人在向自 己一步步走过来..... <妖精旋律> 12某宅穿越,发现自己为一王牌狙击手,刚刚把自己的徒弟一枪撂倒,看着下面的十字疤男 和银发小姑娘不禁脱口而出“就算是垂死挣扎也有点太过分了吧。” 全金 克鲁兹师傅…… 13某宅穿越,发现自己成为一名政府秘密组织老大,身形魁梧,精通体术,更兼有勇有谋, 手下小弟个个精干。眼前红发矮子强则强矣,然被己连番计策攻心,五感去其四,流血过多 ,多处骨折。自己占据天时地利人和不败之境,只差上前一刀来个干脆………… 浪客剑心 14某人穿越,发现自己身处豪宅之中。细一思索,发觉自己精通箭术,出身自魔术师世家, 家族虽败但万事具备,还有一名身材高佻气质御姐全听使唤。正欲一展全脚,突见眼前出现 一个紫发少女说,“哥哥,对不起”…… Fate/Stay Night 15某男穿越,发现自己被钓空中,面前一猥琐恶汉坐在椅子上,身边有4个好像是基佬的家伙 16某宅男穿越,发现自己变成一只白色九尾大妖,是人挡杀人佛挡杀佛,普天之下再无敌手 。心中正暗喜之际,突见面前有一人一妖,那人一手指天曰:“太阳正和我们并肩作战。 潮与虎 17某宅男穿越后发现自己虽然变了女生,可是战斗力却是全大陆最强,用10%的力量就能把 排名仅次于自己的三个同伴打得抬不起头。这时,自己眼前跪着的美少女突然楚楚可怜地说 ,“求求你,给我一个机会…… 大剑 18某废柴穿越,发现自己成进化顶点的终极生物。不老不死,威力无穷,是上一切对于自己 斗不过是食物虫蚁而已。 正当暗爽的时候,发现脚下地面开始震动,一个重伤的人类小子对自己坏笑…… jojo 19某男一睁眼醒来,想起自己是政府特殊作战部队的精英,可靠的队友里既有后方做情报支 援的萌妹子,还有和自己拥有同样灵能力的摩托车打女。 正要举起手里的饮料为构建和谐后宫而干杯的时候,突然发现有蝴蝶飞过。 <Ga Rei Zero/食玲玲> 20某日穿越,发现自己成了一宇宙舰队的指挥官,统领数百万舰队,0机动兵器更是无量大 数,在一个边境小星球附近遭遇了有数万年积怨的敌对民族的一支部队,相互间正摆开阵式 准备大干一场,突然耳边响起悦耳的歌声 <Macross?> 21某死弱宅穿越,发现自己身为某一高中橄榄球队队长,马上即将与另一高中的娘泡球队展 开一场“毫i无意义”的友谊赛,听说对方为了这场比赛进行了一个周的“毫无意义”的特 训。天下着雨,对方身着绿色军服入场!? 全金/短片 22某宅穿越后发现自己变成一貌美正太,边上有个双胞胎loli姐姐。姐弟两一直相依为命, 虽然看似身材柔弱却有一副好身手,而且喜欢玩虐杀和换装的变态游戏。 在一次受命暗杀黑社会人物后被该组织追杀,途中姐姐惨遭不幸自己也快要不行的时候得到 一位热心肠的大哥哥和他朋友的逃亡保护,一路上被大哥哥的温柔所治愈忍不住在大哥哥面 前自爆了一把却遭到了大哥哥朋友的嫉妒。不过所幸最终九死一生安全逃出了组织的追捕, 和大哥哥许下约定跳下了船。 虽然发生了很多事,不过从今以后应该可以过上新生活吧。远处给自己安排新身份的接头人 正在走来,今天的天空可真蓝呀。。。 <Black Lagoon / 黑礁> 23某肥宅穿越,发现自己还是一个死胖子。细细想来,自己是当地首屈一指的奴隶贩子,玩 过无数萝莉御姐。虽无称霸的实力,但淫乐一世不在话下。身边群芳环伺,心想破了处再说 ,发现座下走过来一个不起眼的矮子,开口就是:“我给你介绍一个好女人。” UU白书 24某人一觉醒来,发现自己成了白发美红眼少年,得意之余跑到湖边的残破雕像上唱欢乐颂 ,唱着唱着发现一漂亮的黑发男孩在旁边一脸羞涩地看着自己…… EVA 25某宅男一觉醒来,发现自己无比英俊帅气,银发飘飘,手拿太刀正宗,举手投足毁天灭地 ,纵横捭阖,正欲狂笑,忽见对面一金发小帅哥,手持组合大剑直冲而来,大吼道:“六式 超究武神霸斩!” FF7 26某穿越,自觉魔力无限,法力无边。身边还有一超时代杀人木偶伺候。虽然身高似乎略矮 ,但对于10岁的年龄来说这完全不是问题。就在得意之时,发现对面有一红发男子正左手拿 小抄,右手掏大蒜...耶?为何有大蒜? 27某被发卡无数次宅男一觉醒来,发现自己坐在一张轮椅上,正在欣赏美丽夕阳,身后有一 白色长发超级大美女陪同,略一思索,想起她是自己老婆。正想着晚上回去后可以干什么不 河蟹的事儿,然后突然眼皮一重,太阳落山了。 纸袋aFter? 28一眼镜宅男穿越,清醒后发现自身身材匀称,面貌俊秀,视力破表,身穿一套可飞行的单 兵作战护甲。忽然发现面前站着一位半裸的LOLI,正泫然欲泣的看着他。本想拿棒棒糖喂食 她,结果LOLI转身就跑掉了,远远传来句“怕死谈什么恋爱啊!” 29某宅穿越,发现自己变成一个小loli,身体好像还是木头做的,左眼还带了个眼罩,再仔 细一看还有个红衣金发马尾loli骑在自己身上欲对自己下毒手,心中不禁有点惊慌。还好这 时旁边小正太喊了一句“住手”,红衣loli露出了一个破绽,于是为了保住自己的性命,某 宅毫不犹豫的就用右手的水晶剑下了毒手,红衣loli倒地,从她身上飞出3个红色光球飞入 自己体内。。。。。。 30某宅穿越后发现自己英俊潇洒一表人才,不仅有科技成就搞政治也是一流。此时更是已经 一统卫星地球,号令数万大军,手下还有人挡杀人佛挡杀佛的两位顶尖打手。正要在要塞里 喝咖啡时一粉红战舰从远处冒出。。 Gundam SEED D 31某人穿越,发觉自己武功天下无敌,两个宿敌已经被自己打至奄奄一息,更有其中之一把一 股"世人梦寐以求的力量"送进自己体里,大喜之际,发觉自己已经身怀三颗龙元的力量 ...... 风云 断浪 32某人穿越发现自己身材巨大力量无比 乃守护宇宙和平的光之巨人是也 刚想大展拳脚找找 怪兽晦气 只听见一声"杰~顿..." 33某人穿越发现自己威严健硕身负神力 正变化巨大以雷电之力将一白皮红纹的凶暴光头逼 入绝境 欲痛下杀手时只见那光头将手中兵刃往地下一插大吼一声:"宙斯你赢了!!给老子个 痛快吧!!" 战神 34某人穿越,发现自己成为一拉面师傅。身怀绝技,妹子无数:三无、天然呆、声优...最 终以拉面决胜,抱得美人归,在众人的祝福中开始了新婚旅行 Nadesico 35某废柴一事无成大叔一觉醒来,发现自己身为大制药公司的部长并与社长关系甚好,且有 房有车有娇妻,平时没事骚扰一下女下属开个房打打炮,还有个青春漂亮的女儿,俨然一人 生赢家。虽然面前这个客户一脸刁钻样子给自己脸色看,但自己真是命有贵人,一更长相猥 琐的大叔自称公司员工三下五除二就替自己解决了难题。咦,只是他没事干嘛披条黄毛巾… … 鬼作? 36某宅穿越,发现自己正在干着一个穿着礼园女学院校服的美少女,虽然美少女看似目无表 情毫不在意,但是自己能干上美少女不由得还是内心暗喜,正欲换个姿势继续干的时候,发 现自己右手上拿着小刀.... <空境-痛觉残留?> 37某宅穿越,发觉自己是意气风发的棒球队成员,刚刚开始独居的新生活甲子园有望而且和 隔壁的妹子进展顺利。回到家忽然发现自己的行李都被打开了,而且房间中央坐着个不认识 的穿着自己衣服长发马尾男问:你是谁? 38某日穿越,发觉自己为世上最强者,武功天下第一,手下能人无数,军队所过之处无不摧 枯拉朽,周边诸强不是投降归附就是苟延残喘,整个世界已经在自己手中,正待大展拳脚, 眼前出现一个胸前有7个伤疤的男人 <北斗神拳> 39某宅男一觉醒来,发现自己穿越成白种人,英俊潇洒风流倜傥,正在驾驶一辆小型货车, 车上是价值几十亿美刀的贵重物品,现在只要这批货出手,房子美女什么的都是唾手可得。 志得意满间,前方忽然跳出一黑人和一泥轰人,嘴里大喊着什么 <金克拉?> 40某病弱穿越变成特种部队成员,立时接到解决豪华宾馆里一男一女两个恐怖分子的任务。 跟队友摸索至门口,一马当先一脚踹开门,见男子立于窗前,扣动扳机突突突把其打成筛子 。 以为任务结束了,抬头看见月亮变成血红色… hellsing 41你穿越了,醒了之后发现你拿枪顶着一个白发少年,那少年正猥琐地抚摸着一名少女,少 年扭曲着脸看着你大喊:"只要给本大爷一秒钟……" 42你穿越成了一个全球超强的存在,本体在月球,并且可以吸收地球增强自己的实力 突然 你听到你体内传来了一句:我们的手鲜红如火,它叫我紧抓胜利 G高达? 43你穿越成了地球意志,拥有绝强的力量,你的面前有3个臭虫一样的存在,突然,两个臭 虫手上分别燃起了红色和苍蓝的火焰,另外一个臭虫手指上冒出了白光 44你穿越成了一个美少女,你发现自己没有痛觉,突然,一伙流氓向你走了过来… <空境-痛觉残留> 45你穿越了,你发现自己好像神一样,所有说出口的话都成真了,正在你兴奋的时候,你的 眼角瞥到身后角落里有个晕倒的修女…… 空境-忘却录音 46你穿越成了一个绝对强大的存在,全球能和你媲美的不超过18人 然后 你还有一个可爱的 好朋友 你们连衣服都一样的 然后 你还会驾驶机器人 然后 你被你朋友捏住了 EVA 这寻?…… 47你穿越了,你发现自己是个几乎完美的男人,还有个漂亮的女朋友。这时候,一个男生闯 进了你的教室一把拉住你女朋友让她赶紧跟他走。。。。 48你穿越了,发现你成了个女生,前去探望车祸后性格大变的暗恋对象,然后你推门进去, 发现墙壁周围都是乱七八糟的颜色…… 沙耶之歌 49你穿越了,变成了一个美女,一天你发现你暗恋的上司死了,你很悲伤,然后去看,发现 上司没死,正当你惊喜地靠近他时,他说:“崇拜,是人和人之间最远的距离……” BL EACH 50某男穿越后,发现正趴在一个女人身上运动。观察下四周,好像是个地下室吧,周围还有 一群穿着斗篷蒙面人,看下自己身上衣服,应该是自己人,地面上还有一个魔法阵。是要举 行什么仪式吗?马上整理这具身体的记忆,原来身下这个叫北见什么的女人是祭品啊。那么 不管了,先爽了再说! 黑暗圣经 51某男穿越后发现自己怀抱古典美女,斜倚一残破大楼的阳台边。虽然深受重伤但是战斗已 经结束,并有一强壮但妖媚的男子眼含热泪望着自己。 好一番苦战之后的激情四射,哈哈,虽然不知道是什么地方什么故事,但怀中抱妹又有小弟 的男人必然是主角啊。兴奋中,他颤抖着手抽了一根烟。。。。。 52你两眼一黑,发现穿越成了一个国王,你统治着当时最强盛的联盟,你的儿子刚刚打败了 入侵者正要向你回来报告,在你的面前跪着一名穿着黑甲拿着冒着寒气的巨剑的男子.然后 你会说:你要干什么,我的孩子 冰封王座 53你穿越了,发现很有妹子,这天妹子去你家烧水,你接了个短信…… 54你穿越成了一个杰出新人类,正在和4个同伴抢机体。。你的目标是蓝白条的 Gundam SEED 55你穿越成了一个优秀的杰刚驾驶员 你拥有无比风骚的微操和无比优秀的意识 你接到上级 命令去威吓一下路过的货船 然后远远的看到了一抹绿色…… Gundam UC 杰刚队长 56你穿越成一个特种兵,你忽然发现队伍里有个人被铐着手铐,身后还有几个黄种人,其中 一个人的脸上有疤痕………… 全金 57你穿越成了一个帅气的青年,拥有一身绝世的拳法,身边还有你心爱的人,手下有一帮强 悍的部下,你突然看到一个胸口有七个伤疤的男人向你走来,他说:为了战胜你,我从地狱 回来了! 北斗神拳 南斗的抢了全四郎老婆的人 58你穿越为了一位真祖吸血鬼……魔力无边,手下无数,还有座城堡,某天一个自称是你儿 子的帅气半吸血鬼来找你 双星物语?恶魔城? 59你穿越成了一个富家少爷,拥有全球最热门的游戏的开发权和经营权,你看到一个刺猬头 少年对你说:来决斗吧,就用黑暗游戏! 游戏王 60你穿越成了宇宙最强的存在,可以轻松的毁灭一个星球,当你想大展宏图 征服全宇宙时 ,一个有尾巴的半裸男子对你说:我真的生气了! 龙珠? 61你穿越成了一个镇子黑道的最高统领,你拥有无双的拳法和无比厚实的基础,还有一个天 才哥哥,当你在你家楼顶俯瞰你的势力时,一个红白衣帽的男子向你走来 恶狼传说 62你穿越成了世界最强的魔法师,伸手就可以触及本源,拥有着整个世界。突然,一个男人 闯进你的宫殿大喊:“造物主,我来了!“ 63你穿越了,你是龙族,你很骄傲,一天一个绿色的老人唤醒了你,向你要求永保青春 64你穿越成了英雄,拥有斩杀巨龙的实力,你还有一个美丽的LOLI相伴,你下定决心要永远 保护她,对面走来一个金发赤眼的疯子,嘴里老是说什么,杂种啊,本王什么的 <Fate> Bersarke? 65你穿越了,睁眼看见了一个穿着工作服的好男人坐在长椅上对你说道:“亚拉那一卡?” 好男人阿部 66你穿越了,发现这辈子是一个用枪的风骚男,枪法无敌,面前一个被绑住的双马尾美女, 身后一个神父笑着对你说:“那么,自杀吧!” Fate lancer 67你穿越成了一个男孩,忽然,一个拿着柴刀的漂亮女孩大喊:嘘DA!向你冲过来……… <寒蝉> Rena 68你穿越成为了一个美丽的吸血鬼,你很天才的将吸血鬼血统压制住了,就免去了吸血的冲 动 这时候,你家门铃响了,一个穿着蓝色校服的男生站你家门口 69你穿越了,穿越成一个巨人,你发现你的右手被一个女孩抓住,你刚出左拳去打她,但是 有个刺猬头正右手举拳向你冲来………… Index?? 70你穿越了,发现自己成了大魔王,绑架了公主,每天过得很潇洒,但是你刚想享受的时候 ,一个管道工走了过来,躲开你的火焰禁咒,跳到你身后的开关上…… Mario 71你穿越成了一个暴走族,你发现自己正骑着摩托在校园里耀武扬威。突然,面前走来一个 银色头发的美少女。。。 CLANNAD 72你穿越成了人行界面,此时你的手正在一个无口LOLI的手中,而你另一只手深深的插入对 方。 凉宫? 73你正在大街上闲步走着,忽然发现一个身穿黑色衣服的兜帽男快速的向你冲来,他一把把 你抓起然后举起右手握拳………… 74你穿越了,你发现自己超强,你的好朋友问你 そんな装备で大丈夫か?你习惯性的回答 了一句:大丈夫だ、问题ない! El Shaddai 75你穿越了,发现自己强大无比,可四周一片混沌。这时候,你的右手摸到一把斧子…… 盘古 76你穿越了 成为了一个国家元首的儿子,你拥有无敌的军队 你还是舰长,你还有一个无 比能干的下属 你的下属很聪明的发现了敌人的包围圈 然后通知你 你果断逃跑 突然 你的 下方出现了一艘白色的巨大战舰 77你穿越了,发现你是一个很大的恐怖组织的老板,手下忠心,办事得力,唯一的缺陷就是 你身材比较短小…… 78你穿越了,发现你是一个年少有为的驾驶员的好朋友。他有两个妹子一个活泼过度,一个 无口 激动战舰Nadesico 79你穿越成了一个异兽。。。有强大的电气能力。。。一天。。一个该死的老头用球型道具 抓了你。。。 宠小 80你和一群人一起快乐的旅游,你当时开玩笑,说你的特技是变成食物。 然后遇到大雪,你发现他们用让人蛋疼的目光看着你…… 距离终点还有4天…… 日和-西游记_旅程的终点 81你穿越了,你发现自己是全球最强的人的师傅,你还拥有超级再生的能力和超强的高达, 然后 你徒弟找上门来了 G高达? 82你穿越成了一个不死身美御姐。。。。某天你接到一个少年的委托和他潜入一个地方。。 。中途由于臀部曲线太完美被扫描发现了 记忆女神的女儿们 83你穿越了,你发现自己是个头脑超好的侦探,你追踪一个罪犯已经到了最后一步了,马上 你就能够抓住罪犯了 然后 你的心脏抽了一下 L.L.L. 84你穿越了,发现你被70码了之后身边的人都成了怪物 沙耶之歌 85你穿越了,发现自己是月球之主,你听说地球上很热闹就找了个望远镜,你看到了一个老 头爆了衫双手合拢对着你的方向摆了个造型,旁边还有只大猩猩…… 龙珠? 86你穿越了,发现你和某王女有私情,正当你窃喜时,王女派人来要当时的定情物,你被人 爆了菊花,你临死前把戒指递给了面前的人…… 87你穿越了,发觉自己十分英俊,在学校也很有地位和人气,还有一个很可爱的妹妹,只是 你手中拿着一本伪臣之书。。。 Fate/Stay Night 88你穿越了,你发现地面有个披萨盒子,里面还有半块披萨饼,还有一只手想拿披萨,你忽 然很脑抽的踩了披萨一脚………… 89你穿越了,你发现你是一个很厉害的忍者,教授出了一对强者父子。现在你正和你的徒弟 对峙,你召唤出了一只蛤蟆…… 火影? 90你穿越了,发觉自己是某个组织的大头目,而二头目小妹妹正和你在某间密闭的室内,这 时有个有胡须的金发男孩走了进来。。。 91你穿越了,发现你是一个后宫男的好朋友,一天,后宫男的正宫说请你吃她母亲做的面包 ,还有母亲认识的一个阿姨做的果酱…… CLANNAD? · dd811bc2764827df6fd0c6743cb952d2c6eb1708 Translator 0 38 94 2011-12-09T03:02:27Z HenryHu 1 以内容“[[Category:脚本]] 某在线翻译脚本,参数是gbk编码的字符串…… 用在某在线翻译程序里,每次调一次这个脚本…… 带了一个简...”创建新页面 wikitext text/x-wiki [[Category:脚本]] 某在线翻译脚本,参数是gbk编码的字符串…… 用在某在线翻译程序里,每次调一次这个脚本…… 带了一个简单的缓存,用BDB缓存已经翻译过的东西。 Google Translate API要钱而且很贵,所以后来改Bing了…… <source lang="perl"> #!/usr/bin/perl use DB_File; use URI::Escape; $filename = '/home/henryhu/.tranlate_cache.db'; $res = `echo -n '$ARGV[0]' | iconv -f gbk`; $query = $res; #print $query; $query = uri_escape($query); #print $query; tie %cache, 'DB_File', $filename, O_CREAT|O_RDWR , 0777, $DB_HASH; if ($cache{$query}) { $tag = "F"; $result = $cache{$query}; } else { $tag = "N"; $url = "http://api.microsofttranslator.com/v2/Http.svc/Translate?appId=<Bing API key>&text=$query&from=ja&to=zh-CN"; # $url = "https://www.googleapis.com/language/translate/v2?key=<Google API key>&q=$query&source=ja&target=zh-CN"; $res2 = `curl -s '$url'`; # print $res2; foreach ($res2) { # if (/"translatedText":\s*"(.*)"/) if (/<string[^>]*>(.*)/) { $result = $1; } } $cache{$query} = $result; } $omit = 0; if ($cache{"last"}) { if ($cache{"last"} eq $query) { $omit = 1; } } if (not $omit) { print "$tag $result\n"; } $cache{"last"} = $query; untie %cache; </source> a251b63d3415bb81ffbd6c7ff6d8b1e3efa52b92 Proceedings 0 39 95 2011-12-10T21:10:19Z HenryHu 1 以内容“ == SOSP == [http://sigops.org/sosp/sosp11/current/index.html 2011] == OSDI == [http://www.usenix.org/event/osdi10/tech/ 2010] [http://www.usenix.org/events/osdi08/tec...”创建新页面 wikitext text/x-wiki == SOSP == [http://sigops.org/sosp/sosp11/current/index.html 2011] == OSDI == [http://www.usenix.org/event/osdi10/tech/ 2010] [http://www.usenix.org/events/osdi08/tech/ 2008] [http://www.usenix.org/events/osdi06/tech/ 2006] [http://www.usenix.org/events/osdi04/tech/ 2004] [http://www.usenix.org/events/osdi02/tech.html 2002] [http://www.usenix.org/events/osdi2000/tech.html 2000] 0ae85bb3a4cffd6dc58baa84cf687e31b4fc21a9 96 95 2011-12-10T21:11:03Z HenryHu 1 /* OSDI */ wikitext text/x-wiki == SOSP == [http://sigops.org/sosp/sosp11/current/index.html 2011] == OSDI == [http://www.usenix.org/event/osdi10/tech/ 2010/9th] [http://www.usenix.org/events/osdi08/tech/ 2008/8th] [http://www.usenix.org/events/osdi06/tech/ 2006/7th] [http://www.usenix.org/events/osdi04/tech/ 2004/6th] [http://www.usenix.org/events/osdi02/tech.html 2002/5th] [http://www.usenix.org/events/osdi2000/tech.html 2000/4th] 62ae165d9b3ccdfb456e57625932381fb3cda3e0 Natsu no Arashi 0 40 98 2012-01-05T21:03:59Z HenryHu 1 以内容“某无意义流程图 create(Cutie Cherry) wrapin(WrapA) group A with X. Cherry replace(Cutie Cherry with X. Cherry) wrapout(WrapC) group A with Cut...”创建新页面 wikitext text/x-wiki 某无意义流程图 create(Cutie Cherry) wrapin(WrapA) group A with X. Cherry replace(Cutie Cherry with X. Cherry) wrapout(WrapC) group A with Cutie Cherry exist(Milk(Pass(2month), Label(TM))) throw(^Milk to Basket) buy(Milk(New, Label(AL))) buy(Many(Good. Cherry)) circle(Good. Cherry to Dish from Tower(Good. Cherry), X. Cherry from Dish to ^Tower) wrapin(WrapB) group B with Milk(?, Label(AL)) transform(Good. Cherry to Extreme. Cherry in Dish) wrapout(WrapB) group B put(Milk(?, Label(AL)) into Fridge) wrapout(WrapA) group A with X. Cherry wrapin(WrapC) group A with Cutie. Cherry left(Tower(Cherry), X. Cherry) disable(Cutie Cherry) drink(Tea(_, X. Cherry)) 628dffb8048f49794045a9815042374129f5c409 99 98 2012-01-05T21:05:54Z HenryHu 1 [[夏之岚]]移动到[[Natsu no Arashi]] wikitext text/x-wiki 某无意义流程图 create(Cutie Cherry) wrapin(WrapA) group A with X. Cherry replace(Cutie Cherry with X. Cherry) wrapout(WrapC) group A with Cutie Cherry exist(Milk(Pass(2month), Label(TM))) throw(^Milk to Basket) buy(Milk(New, Label(AL))) buy(Many(Good. Cherry)) circle(Good. Cherry to Dish from Tower(Good. Cherry), X. Cherry from Dish to ^Tower) wrapin(WrapB) group B with Milk(?, Label(AL)) transform(Good. Cherry to Extreme. Cherry in Dish) wrapout(WrapB) group B put(Milk(?, Label(AL)) into Fridge) wrapout(WrapA) group A with X. Cherry wrapin(WrapC) group A with Cutie. Cherry left(Tower(Cherry), X. Cherry) disable(Cutie Cherry) drink(Tea(_, X. Cherry)) 628dffb8048f49794045a9815042374129f5c409 100 99 2012-01-05T21:07:04Z HenryHu 1 wikitext text/x-wiki 某无意义流程图 create(Cutie Cherry) wrapin(WrapA) group A with X. Cherry replace(Cutie Cherry with X. Cherry) wrapout(WrapC) group A with Cutie Cherry exist(Milk(Pass(2month), Label(TM))) throw(^Milk to Basket) buy(Milk(New, Label(AL))) buy(Many(Good. Cherry)) circle(Good. Cherry to Dish from Tower(Good. Cherry), X. Cherry from Dish to ^Tower) wrapin(WrapB) group B with Milk(?, Label(AL)) transform(Good. Cherry to Extreme. Cherry in Dish) wrapout(WrapB) group B put(Milk(?, Label(AL)) into Fridge) wrapout(WrapA) group A with X. Cherry wrapin(WrapC) group A with Cutie. Cherry left(Tower(Cherry), X. Cherry) disable(Cutie Cherry) drink(Tea(_, X. Cherry)) b6ff9a2ec849295539b9064b39de10ca223674a2 Cookbook 0 41 101 2012-01-08T22:01:47Z HenryHu 1 以内容“做过/别人做过的菜列表 * 炒卷心菜 * 炒刀豆 * 炒豆芽 * 干煸四季豆 * 番茄炒蛋 * 荷包蛋 * 可乐鸡块 * 炸鸡块 * 卷心菜炒肉 * ...”创建新页面 wikitext text/x-wiki 做过/别人做过的菜列表 * 炒卷心菜 * 炒刀豆 * 炒豆芽 * 干煸四季豆 * 番茄炒蛋 * 荷包蛋 * 可乐鸡块 * 炸鸡块 * 卷心菜炒肉 * 豆芽炒肉 * 茄子炒肉 bc9321b2ef29ec8d69a5f405c60c21d05a814c5e 102 101 2012-01-08T22:03:02Z HenryHu 1 wikitext text/x-wiki 做过/别人做过的菜列表 * 炒卷心菜 * 炒刀豆 * 炒豆芽 * 干煸四季豆 * 番茄炒蛋 * 荷包蛋 * 可乐鸡块 * 炸鸡块 * 卷心菜炒肉 * 豆芽炒肉 * 茄子炒肉 * 土豆丝炒肉 d22c0442bcda8ab89cc6e1d2e227b2790ee156e2 114 102 2012-01-27T02:26:31Z HenryHu 1 wikitext text/x-wiki 做过/别人做过的菜列表 * 炒卷心菜 * 炒刀豆 * 炒豆芽 * 干煸四季豆 * 炒青菜 * 番茄炒蛋 * 荷包蛋 * [[韭菜炒蛋]] * 可乐鸡块 * 炸鸡块 * 卷心菜炒肉 * 豆芽炒肉 * 茄子炒肉 * 土豆丝炒肉 * [[韭菜炒肉]] f6a39e31ce7df3bbdcd5b853484631c979d39697 120 114 2012-01-28T20:05:05Z HenryHu 1 wikitext text/x-wiki 做过/别人做过的菜列表 * 炒卷心菜 * 炒刀豆 * 炒豆芽 * 干煸四季豆 * 炒青菜 * [[炒土豆丝]] * 番茄炒蛋 * 荷包蛋 * [[韭菜炒蛋]] * 可乐鸡块 * 炸鸡块 * 卷心菜炒肉 * 豆芽炒肉 * 茄子炒肉 * 土豆丝炒肉 * [[韭菜炒肉]] 338b0f23d5cf3681ff01ce46d5af7cb255446c7f AFS file 0 42 103 2012-01-09T04:49:13Z HenryHu 1 以内容“某文件格式 mac.afs: found records @ tail 1st filename @ 2C6000 2nd filename @ 2C6030 3rd filename @ 2C6060 -> file record: 0x30 = 48 bytes 1st record: 0x2C6000 ...”创建新页面 wikitext text/x-wiki 某文件格式 mac.afs: found records @ tail 1st filename @ 2C6000 2nd filename @ 2C6030 3rd filename @ 2C6060 -> file record: 0x30 = 48 bytes 1st record: 0x2C6000 BAD.BIP 00..00 0x2C6020 D9 07 08 00 0x2C6024 0D 00 0A 00 0x2C6028 06 00 20 00 -> + 00 00 02 00 0x2C602C 31 01 00 00 305 2nd record: 0x2C6030 KA01.BIP 00..00 0x2C6050 D9 07 08 00 0x2C6054 0D 00 0A 00 0x2C6058 06 00 22 00 0x2C605C 00 10 00 00 4096 3rd record: 0x2C6060 KA02.BIP 00..00 0x2C6080 D9 07 08 00 0x2C6080 0D 00 0A 00 0x2C6080 06 00 24 00 0x2C6080 7F 13 00 00 4991 Last record @ 0x2C9900 Total: 305 = 0x131 records Last file start @ 2C5800 -> Min block size: 0x200 = 512 bytes 1st / 2nd start @ 0x1000 -? 0x237F size: 0x137F next start @ 0x2800 diff: 0x4000 -? 0x65B7 size: 0x3DB7 next start @ 0x6800 diff: 0x4000 next start @ 0xA800 -? 0x13359 size: 0x8B59 diff: 0x9000 next start @ 0x13800 diff: b1ced6cb3e728f9ddc4310e1a02b3ed05007b75a 104 103 2012-01-09T08:32:23Z HenryHu 1 wikitext text/x-wiki 某文件格式 <pre> mac.afs: found records @ tail 1st filename @ 2C6000 2nd filename @ 2C6030 3rd filename @ 2C6060 -> file record: 0x30 = 48 bytes 1st record: 0x2C6000 BAD.BIP 00..00 0x2C6020 D9 07 08 00 0x2C6024 0D 00 0A 00 0x2C6028 06 00 20 00 -> + 00 00 02 00 0x2C602C 31 01 00 00 305 -> file count? 2nd record: 0x2C6030 KA01.BIP 00..00 0x2C6050 D9 07 08 00 -> static 0x2C6054 0D 00 0A 00 -> static 0x2C6058 06 00 22 00 -> increasing ? 0x2C605C 00 10 00 00 4096 -> 1st start 3rd record: 0x2C6060 KA02.BIP 00..00 0x2C6080 D9 07 08 00 0x2C6080 0D 00 0A 00 0x2C6080 06 00 24 00 0x2C6080 7F 13 00 00 4991 -> 1st size Last record @ 0x2C9900 Total: 305 = 0x131 records Last file start @ 2C5800 -> Min block size: 0x200 = 512 bytes 1st / 2nd start @ 0x1000 -? 0x237F size: 0x137F -> KA02.BIP next start @ 0x2800 diff: 0x4000 -? 0x65B8 size: 0x3DB8 -> KA04.BIP next start @ 0x6800 diff: 0x4000 size: 0xC63C -> KA06.BIP next start @ 0xA800 size: 0x379C -> KA08.BIP next start @ 0xE000 -? 0x1335A size: 0x535A diff: 0x5800 -> KAO.BIP next start @ 0x13800 diff: Header: 0x00 AFS\0 0x0004 31 01 00 00 -> 0x131 = 305: record count 0x0008 00 10 00 00 -> 1st start 0x000C 7F 13 00 00 -> 1st size 0001000: 0823 0000 ff09 0f06 0000 6008 005f 0900 .#........`.._.. 0001010: 0860 fff5 f009 f9f0 ff4c 008c 0012 0319 .`.......L...... 0001020: 00ff 1a00 6580 0100 65a0 ff01 0033 0100 ....e...e....3.. 0001030: 01ff 10bb 3510 e8f3 6400 02eb f0c0 8fff ....5...d....... 0001040: 1e00 0f2b 0231 0fea f165 ff02 5a00 6520 ...+.1...e..Z.e 0x0010 00 28 00 00 -> 2nd start 0x0014 B8 3D 00 00 -> 2nd size 0002800: 0c6d 0000 ff09 0f06 0000 6008 00ff 1203 .m........`..... 0002810: 1900 1a00 6580 ff1e 0065 a001 0033 01bf ....e....e...3.. 0002820: 0001 ff10 0010 e8f3 65ff 0201 0065 2001 ........e....e . 0002830: 0009 ef00 0860 0a19 0009 6014 b619 0001 .....`....`..... 0002840: a0ec f000 0229 0203 be29 021a 6000 004c .....)...)..`..L 0x0018 00 68 00 00 -> 3rd start 0x001C C6 3C 00 00 -> 3rd size 0006800: 6367 0000 ff09 0f06 0000 6008 00df 0900 cg........`..... 0006810: 0860 0af5 f009 60ff 1900 4c00 4f00 5300 .`....`...L.O.S. 0006820: ff74 1065 8001 0065 a0ff 0100 3301 0001 .t.e...e....3... 0006830: ff10 bb4f 10e8 f364 0002 ebf0 c08f ff2d ...O...d.......- 0006840: 000f 2902 2f0f eaf1 41ff 043f 0340 003e ..)./...A..?.@.> 0x0020 00 A8 00 00 -> 4th start 0x0024 9C 37 00 00 -> 4th size 000a800: b163 0000 ff09 0f06 0000 6008 00df 0900 .c........`..... 000a810: 0860 0af5 f009 60ff 1b00 4c00 5200 5300 .`....`...L.R.S. 000a820: ff70 1065 8001 0065 a0ff 0100 3301 0001 .p.e...e....3... 000a830: ff10 fb0a 10e8 f341 043f 0340 ff00 3e00 .......A.?.@..>. 000a840: 3b80 3c80 3bff 8039 033a 0038 000f ff00 ;.<.;..9.:.8.... 0x0028 00 E0 00 00 -> 5th start 0x002C 5A 53 00 00 -> 5th size 0x0030 00 38 01 00 -> 6th start 于是可以解出来 但是貌似多数文件都压缩了…… ADX = Ogg BIP: Many possible formats... T2P: Image, ... </pre> <source lang="cpp"> #include <iostream> #include <fcntl.h> #include <vector> #include <string> #include <sys/endian.h> #include <errno.h> #include <sys/stat.h> #include <zlib.h> using namespace std; typedef unsigned char uchar; int uncompress(char *buf, int size, char *newbuf, int newsize) { int ret; z_stream strm; /* allocate inflate state */ strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = 0; strm.next_in = Z_NULL; ret = inflateInit(&strm); if (ret != Z_OK) return ret; /* decompress until deflate stream ends or end of file */ strm.avail_in = size; strm.next_in = (Bytef *)buf; /* run inflate() on input until output buffer not full */ strm.avail_out = newsize; strm.next_out = (Bytef *)newbuf; ret = inflate(&strm, Z_NO_FLUSH); if(ret == Z_STREAM_ERROR) /* state not clobbered */ return ret; switch (ret) { case Z_NEED_DICT: ret = Z_DATA_ERROR; /* and fall through */ case Z_DATA_ERROR: case Z_MEM_ERROR: (void)inflateEnd(&strm); return ret; } /* done when inflate() says it's done */ /* clean up and return */ (void)inflateEnd(&strm); return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; } string dump(unsigned char *data) { char buf[20]; snprintf(buf, 20, "%02x %02x %02x %02x", data[0], data[1], data[2], data[3]); return string(buf); } void toh(uint32_t &x) { x = le32toh(x); } class File { int size, offset; uchar sig1[4], sig2[4], mark[4], xx[4]; string name; public: File(int _offset, int _size) : size(_size), offset(_offset) {} int get_size() { return size; } int get_offset() { return offset; } const string & get_name() { return name; } void set_info(const string& _name, uchar *_sig1, uchar *_sig2, uchar *_mark, uchar *_xx) { name = _name; memcpy(sig1, _sig1, 4); memcpy(sig2, _sig1, 4); memcpy(mark, _mark, 4); memcpy(xx, _xx, 4); } }; int main(int argc, char **argv) { if (argc < 2) { cout << "usage: " << argv[0] << " <afs file> [<output dir>]" << endl; return -1; } char head[4]; int f = open(argv[1], O_RDONLY); if (f < 0) { cout << "fail to open file: " << errno << endl; return -2; } read(f, head, 4); if (memcmp(head, "AFS\0", 4) != 0) { cout << "signature mismatch!\n" << endl; close(f); return 1; } vector<File> files; uint32_t filecount; read(f, &filecount, 4); filecount = le32toh(filecount); cout << "file count: " << filecount << endl; // last file: directory for (int i=0; i<filecount+1; i++) { uint32_t offset, size; read(f, &offset, 4); read(f, &size, 4); toh(offset); toh(size); if ((size == 0) && (i == filecount)) { // ugly state: no last record int x = files[i-1].get_offset() + files[i-1].get_size() + 1; lseek(f, x, SEEK_SET); char ch; read(f, &ch, 1); while (ch == 0) { read(f, &ch, 1); x++; } offset = x; size = 0x30 * filecount; } files.push_back(File(offset, size)); // cout << "File " << i << ": offset=" << hex << files[i].get_offset() << ",size=" << size << "#" << dec << size << dec << endl; } for (int i=0; i<filecount; i++) { lseek(f, files[filecount].get_offset() + 0x30 * i, SEEK_SET); char name[33]; name[32] = '\0'; read(f, name, 32); string sname(name); unsigned char sig1[4]; unsigned char sig2[4]; read(f, sig1, 4); read(f, sig2, 4); unsigned char mark[4]; read(f, mark, 4); unsigned char xx[4]; read(f, xx, 4); files[i].set_info(sname, sig1, sig2, mark, xx); cout << "File " << i << ": name=" << sname << ",offset=" << hex << files[i].get_offset() << ",size=" << files[i].get_size() << dec << endl; cout << "sig1=" << dump(sig1) << ",sig2=" << dump(sig2) << ",mark=" << dump(mark) << ",mock=" << dump(xx) << endl; } if (argc > 2) { string destdir = argv[2]; mkdir(destdir.c_str(), 0755); int bufsize = 0; char *buf = NULL; char *unbuf = NULL; int unbufsize = 0; for (int i=0; i<filecount; i++) { File &frec = files[i]; lseek(f, frec.get_offset(), SEEK_SET); if (frec.get_size() > bufsize) { if (buf) delete []buf; buf = new char[frec.get_size()]; } int cnt = read(f, buf, frec.get_size()); if (cnt != frec.get_size()) { cerr << "warning: partial read for " << frec.get_name() << " " << cnt << " instead of " << frec.get_size() << " errno " << errno << endl; } string destpath = destdir + "/" + frec.get_name(); int outf = open(destpath.c_str(), O_WRONLY | O_CREAT, 0644); if (outf < 0) { cerr << "failed to open output file for " << destpath << " : " << errno << endl; } else { cout << "writing to " << destpath << " size: " << cnt << endl; write(outf, buf, cnt); close(outf); } if (argc > 3) { // uncompress, does not work... uint32_t oldsize; memcpy(&oldsize, buf, 4); toh(oldsize); if (oldsize > unbufsize) { if (unbuf) delete []unbuf; unbuf = new char[oldsize]; } int ret = uncompress(buf+0x8, cnt-0x8, unbuf, oldsize); if (ret != Z_OK) { cerr << "uncompress failed! " << ret << endl; } else { string undest = destdir + "/" + "_" + frec.get_name(); int outunf = open(undest.c_str(), O_WRONLY | O_CREAT, 0644); if (outunf < 0) { cerr << "failed to open output file for " << undest << " : " << errno << endl; } else { cout << "writing to " << undest << " size: " << oldsize << endl; write(outunf, unbuf, oldsize); close(outunf); } } } } } } </source> 80fc8a4b75f2ffa8ec72b26499931192383163a3 105 104 2012-01-09T22:46:41Z HenryHu 1 wikitext text/x-wiki 某文件格式 <pre> mac.afs: found records @ tail 1st filename @ 2C6000 2nd filename @ 2C6030 3rd filename @ 2C6060 -> file record: 0x30 = 48 bytes 1st record: 0x2C6000 BAD.BIP 00..00 0x2C6020 D9 07 08 00 0x2C6024 0D 00 0A 00 0x2C6028 06 00 20 00 -> + 00 00 02 00 0x2C602C 31 01 00 00 305 -> file count? 2nd record: 0x2C6030 KA01.BIP 00..00 0x2C6050 D9 07 08 00 -> static 0x2C6054 0D 00 0A 00 -> static 0x2C6058 06 00 22 00 -> increasing ? 0x2C605C 00 10 00 00 4096 -> 1st start 3rd record: 0x2C6060 KA02.BIP 00..00 0x2C6080 D9 07 08 00 0x2C6080 0D 00 0A 00 0x2C6080 06 00 24 00 0x2C6080 7F 13 00 00 4991 -> 1st size Last record @ 0x2C9900 Total: 305 = 0x131 records Last file start @ 2C5800 -> Min block size: 0x200 = 512 bytes 1st / 2nd start @ 0x1000 -? 0x237F size: 0x137F -> KA02.BIP next start @ 0x2800 diff: 0x4000 -? 0x65B8 size: 0x3DB8 -> KA04.BIP next start @ 0x6800 diff: 0x4000 size: 0xC63C -> KA06.BIP next start @ 0xA800 size: 0x379C -> KA08.BIP next start @ 0xE000 -? 0x1335A size: 0x535A diff: 0x5800 -> KAO.BIP next start @ 0x13800 diff: Header: 0x00 AFS\0 0x0004 31 01 00 00 -> 0x131 = 305: record count 0x0008 00 10 00 00 -> 1st start 0x000C 7F 13 00 00 -> 1st size 0001000: 0823 0000 ff09 0f06 0000 6008 005f 0900 .#........`.._.. 0001010: 0860 fff5 f009 f9f0 ff4c 008c 0012 0319 .`.......L...... 0001020: 00ff 1a00 6580 0100 65a0 ff01 0033 0100 ....e...e....3.. 0001030: 01ff 10bb 3510 e8f3 6400 02eb f0c0 8fff ....5...d....... 0001040: 1e00 0f2b 0231 0fea f165 ff02 5a00 6520 ...+.1...e..Z.e 0x0010 00 28 00 00 -> 2nd start 0x0014 B8 3D 00 00 -> 2nd size 0002800: 0c6d 0000 ff09 0f06 0000 6008 00ff 1203 .m........`..... 0002810: 1900 1a00 6580 ff1e 0065 a001 0033 01bf ....e....e...3.. 0002820: 0001 ff10 0010 e8f3 65ff 0201 0065 2001 ........e....e . 0002830: 0009 ef00 0860 0a19 0009 6014 b619 0001 .....`....`..... 0002840: a0ec f000 0229 0203 be29 021a 6000 004c .....)...)..`..L 0x0018 00 68 00 00 -> 3rd start 0x001C C6 3C 00 00 -> 3rd size 0006800: 6367 0000 ff09 0f06 0000 6008 00df 0900 cg........`..... 0006810: 0860 0af5 f009 60ff 1900 4c00 4f00 5300 .`....`...L.O.S. 0006820: ff74 1065 8001 0065 a0ff 0100 3301 0001 .t.e...e....3... 0006830: ff10 bb4f 10e8 f364 0002 ebf0 c08f ff2d ...O...d.......- 0006840: 000f 2902 2f0f eaf1 41ff 043f 0340 003e ..)./...A..?.@.> 0x0020 00 A8 00 00 -> 4th start 0x0024 9C 37 00 00 -> 4th size 000a800: b163 0000 ff09 0f06 0000 6008 00df 0900 .c........`..... 000a810: 0860 0af5 f009 60ff 1b00 4c00 5200 5300 .`....`...L.R.S. 000a820: ff70 1065 8001 0065 a0ff 0100 3301 0001 .p.e...e....3... 000a830: ff10 fb0a 10e8 f341 043f 0340 ff00 3e00 .......A.?.@..>. 000a840: 3b80 3c80 3bff 8039 033a 0038 000f ff00 ;.<.;..9.:.8.... 0x0028 00 E0 00 00 -> 5th start 0x002C 5A 53 00 00 -> 5th size 0x0030 00 38 01 00 -> 6th start 于是可以解出来 但是貌似多数文件都压缩了…… ADX = Ogg BIP: Many possible formats... T2P: Image, ... Update: 其实都是标准的[[LZSS]]压缩,只是我原来不知道还有那么些恶心的地方,于是搞了好久…… 图片都是TIM2格式,据说是PS2的?里面包着奇怪的东西,多数是原封不动的PNG 脚本还不清楚,反正最后有字符串库,前面不知道是啥…… </pre> <source lang="cpp"> #include <iostream> #include <fcntl.h> #include <vector> #include <string> #include <sys/endian.h> #include <errno.h> #include <sys/stat.h> #include <zlib.h> using namespace std; typedef unsigned char uchar; string dump(unsigned char *data) { char buf[20]; snprintf(buf, 20, "%02x %02x %02x %02x", data[0], data[1], data[2], data[3]); return string(buf); } void toh(uint32_t &x) { x = le32toh(x); } class File { int size, offset; uchar sig1[4], sig2[4], mark[4], xx[4]; string name; public: File(int _offset, int _size) : size(_size), offset(_offset) {} int get_size() { return size; } int get_offset() { return offset; } const string & get_name() { return name; } void set_info(const string& _name, uchar *_sig1, uchar *_sig2, uchar *_mark, uchar *_xx) { name = _name; memcpy(sig1, _sig1, 4); memcpy(sig2, _sig1, 4); memcpy(mark, _mark, 4); memcpy(xx, _xx, 4); } }; int main(int argc, char **argv) { if (argc < 2) { cout << "usage: " << argv[0] << " <afs file> [<output dir>]" << endl; return -1; } char head[4]; int f = open(argv[1], O_RDONLY); if (f < 0) { cout << "fail to open file: " << errno << endl; return -2; } read(f, head, 4); if (memcmp(head, "AFS\0", 4) != 0) { cout << "signature mismatch!\n" << endl; close(f); return 1; } vector<File> files; uint32_t filecount; read(f, &filecount, 4); filecount = le32toh(filecount); cout << "file count: " << filecount << endl; // last file: directory for (int i=0; i<filecount+1; i++) { uint32_t offset, size; read(f, &offset, 4); read(f, &size, 4); toh(offset); toh(size); if ((size == 0) && (i == filecount)) { // ugly state: no last record int x = files[i-1].get_offset() + files[i-1].get_size() + 1; lseek(f, x, SEEK_SET); char ch; read(f, &ch, 1); while (ch == 0) { read(f, &ch, 1); x++; } offset = x; size = 0x30 * filecount; } files.push_back(File(offset, size)); // cout << "File " << i << ": offset=" << hex << files[i].get_offset() << ",size=" << size << "#" << dec << size << dec << endl; } for (int i=0; i<filecount; i++) { lseek(f, files[filecount].get_offset() + 0x30 * i, SEEK_SET); char name[33]; name[32] = '\0'; read(f, name, 32); string sname(name); unsigned char sig1[4]; unsigned char sig2[4]; read(f, sig1, 4); read(f, sig2, 4); unsigned char mark[4]; read(f, mark, 4); unsigned char xx[4]; read(f, xx, 4); files[i].set_info(sname, sig1, sig2, mark, xx); cout << "File " << i << ": name=" << sname << ",offset=" << hex << files[i].get_offset() << ",size=" << files[i].get_size() << dec << endl; cout << "sig1=" << dump(sig1) << ",sig2=" << dump(sig2) << ",mark=" << dump(mark) << ",mock=" << dump(xx) << endl; } if (argc > 2) { string destdir = argv[2]; mkdir(destdir.c_str(), 0755); int bufsize = 0; char *buf = NULL; char *unbuf = NULL; int unbufsize = 0; for (int i=0; i<filecount; i++) { File &frec = files[i]; lseek(f, frec.get_offset(), SEEK_SET); if (frec.get_size() > bufsize) { if (buf) delete []buf; buf = new char[frec.get_size()]; } int cnt = read(f, buf, frec.get_size()); if (cnt != frec.get_size()) { cerr << "warning: partial read for " << frec.get_name() << " " << cnt << " instead of " << frec.get_size() << " errno " << errno << endl; } string destpath = destdir + "/" + frec.get_name(); int outf = open(destpath.c_str(), O_WRONLY | O_CREAT, 0644); if (outf < 0) { cerr << "failed to open output file for " << destpath << " : " << errno << endl; } else { cout << "writing to " << destpath << " size: " << cnt << endl; write(outf, buf, cnt); close(outf); } } } } </source> d52aef0b07a051c00775f257c0f3bf1df48553cf 106 105 2012-01-09T22:47:42Z HenryHu 1 wikitext text/x-wiki 某文件格式 <pre> mac.afs: found records @ tail 1st filename @ 2C6000 2nd filename @ 2C6030 3rd filename @ 2C6060 -> file record: 0x30 = 48 bytes 1st record: 0x2C6000 BAD.BIP 00..00 0x2C6020 D9 07 08 00 0x2C6024 0D 00 0A 00 0x2C6028 06 00 20 00 -> + 00 00 02 00 0x2C602C 31 01 00 00 305 -> file count? 2nd record: 0x2C6030 KA01.BIP 00..00 0x2C6050 D9 07 08 00 -> static 0x2C6054 0D 00 0A 00 -> static 0x2C6058 06 00 22 00 -> increasing ? 0x2C605C 00 10 00 00 4096 -> 1st start 3rd record: 0x2C6060 KA02.BIP 00..00 0x2C6080 D9 07 08 00 0x2C6080 0D 00 0A 00 0x2C6080 06 00 24 00 0x2C6080 7F 13 00 00 4991 -> 1st size Last record @ 0x2C9900 Total: 305 = 0x131 records Last file start @ 2C5800 -> Min block size: 0x200 = 512 bytes 1st / 2nd start @ 0x1000 -? 0x237F size: 0x137F -> KA02.BIP next start @ 0x2800 diff: 0x4000 -? 0x65B8 size: 0x3DB8 -> KA04.BIP next start @ 0x6800 diff: 0x4000 size: 0xC63C -> KA06.BIP next start @ 0xA800 size: 0x379C -> KA08.BIP next start @ 0xE000 -? 0x1335A size: 0x535A diff: 0x5800 -> KAO.BIP next start @ 0x13800 diff: Header: 0x00 AFS\0 0x0004 31 01 00 00 -> 0x131 = 305: record count 0x0008 00 10 00 00 -> 1st start 0x000C 7F 13 00 00 -> 1st size 0001000: 0823 0000 ff09 0f06 0000 6008 005f 0900 .#........`.._.. 0001010: 0860 fff5 f009 f9f0 ff4c 008c 0012 0319 .`.......L...... 0001020: 00ff 1a00 6580 0100 65a0 ff01 0033 0100 ....e...e....3.. 0001030: 01ff 10bb 3510 e8f3 6400 02eb f0c0 8fff ....5...d....... 0001040: 1e00 0f2b 0231 0fea f165 ff02 5a00 6520 ...+.1...e..Z.e 0x0010 00 28 00 00 -> 2nd start 0x0014 B8 3D 00 00 -> 2nd size 0002800: 0c6d 0000 ff09 0f06 0000 6008 00ff 1203 .m........`..... 0002810: 1900 1a00 6580 ff1e 0065 a001 0033 01bf ....e....e...3.. 0002820: 0001 ff10 0010 e8f3 65ff 0201 0065 2001 ........e....e . 0002830: 0009 ef00 0860 0a19 0009 6014 b619 0001 .....`....`..... 0002840: a0ec f000 0229 0203 be29 021a 6000 004c .....)...)..`..L 0x0018 00 68 00 00 -> 3rd start 0x001C C6 3C 00 00 -> 3rd size 0006800: 6367 0000 ff09 0f06 0000 6008 00df 0900 cg........`..... 0006810: 0860 0af5 f009 60ff 1900 4c00 4f00 5300 .`....`...L.O.S. 0006820: ff74 1065 8001 0065 a0ff 0100 3301 0001 .t.e...e....3... 0006830: ff10 bb4f 10e8 f364 0002 ebf0 c08f ff2d ...O...d.......- 0006840: 000f 2902 2f0f eaf1 41ff 043f 0340 003e ..)./...A..?.@.> 0x0020 00 A8 00 00 -> 4th start 0x0024 9C 37 00 00 -> 4th size 000a800: b163 0000 ff09 0f06 0000 6008 00df 0900 .c........`..... 000a810: 0860 0af5 f009 60ff 1b00 4c00 5200 5300 .`....`...L.R.S. 000a820: ff70 1065 8001 0065 a0ff 0100 3301 0001 .p.e...e....3... 000a830: ff10 fb0a 10e8 f341 043f 0340 ff00 3e00 .......A.?.@..>. 000a840: 3b80 3c80 3bff 8039 033a 0038 000f ff00 ;.<.;..9.:.8.... 0x0028 00 E0 00 00 -> 5th start 0x002C 5A 53 00 00 -> 5th size 0x0030 00 38 01 00 -> 6th start </pre> 于是可以解出来 但是貌似多数文件都压缩了…… * ADX = Ogg * BIP: Many possible formats... * T2P: Image, ... Update: 其实都是标准的[[LZSS]]压缩,只是我原来不知道还有那么些恶心的地方,于是搞了好久…… 图片都是TIM2格式,据说是PS2的?里面包着奇怪的东西,多数是原封不动的PNG BIP有些是脚本,格式还不清楚,反正最后有字符串库,前面不知道是啥…… <source lang="cpp"> #include <iostream> #include <fcntl.h> #include <vector> #include <string> #include <sys/endian.h> #include <errno.h> #include <sys/stat.h> #include <zlib.h> using namespace std; typedef unsigned char uchar; string dump(unsigned char *data) { char buf[20]; snprintf(buf, 20, "%02x %02x %02x %02x", data[0], data[1], data[2], data[3]); return string(buf); } void toh(uint32_t &x) { x = le32toh(x); } class File { int size, offset; uchar sig1[4], sig2[4], mark[4], xx[4]; string name; public: File(int _offset, int _size) : size(_size), offset(_offset) {} int get_size() { return size; } int get_offset() { return offset; } const string & get_name() { return name; } void set_info(const string& _name, uchar *_sig1, uchar *_sig2, uchar *_mark, uchar *_xx) { name = _name; memcpy(sig1, _sig1, 4); memcpy(sig2, _sig1, 4); memcpy(mark, _mark, 4); memcpy(xx, _xx, 4); } }; int main(int argc, char **argv) { if (argc < 2) { cout << "usage: " << argv[0] << " <afs file> [<output dir>]" << endl; return -1; } char head[4]; int f = open(argv[1], O_RDONLY); if (f < 0) { cout << "fail to open file: " << errno << endl; return -2; } read(f, head, 4); if (memcmp(head, "AFS\0", 4) != 0) { cout << "signature mismatch!\n" << endl; close(f); return 1; } vector<File> files; uint32_t filecount; read(f, &filecount, 4); filecount = le32toh(filecount); cout << "file count: " << filecount << endl; // last file: directory for (int i=0; i<filecount+1; i++) { uint32_t offset, size; read(f, &offset, 4); read(f, &size, 4); toh(offset); toh(size); if ((size == 0) && (i == filecount)) { // ugly state: no last record int x = files[i-1].get_offset() + files[i-1].get_size() + 1; lseek(f, x, SEEK_SET); char ch; read(f, &ch, 1); while (ch == 0) { read(f, &ch, 1); x++; } offset = x; size = 0x30 * filecount; } files.push_back(File(offset, size)); // cout << "File " << i << ": offset=" << hex << files[i].get_offset() << ",size=" << size << "#" << dec << size << dec << endl; } for (int i=0; i<filecount; i++) { lseek(f, files[filecount].get_offset() + 0x30 * i, SEEK_SET); char name[33]; name[32] = '\0'; read(f, name, 32); string sname(name); unsigned char sig1[4]; unsigned char sig2[4]; read(f, sig1, 4); read(f, sig2, 4); unsigned char mark[4]; read(f, mark, 4); unsigned char xx[4]; read(f, xx, 4); files[i].set_info(sname, sig1, sig2, mark, xx); cout << "File " << i << ": name=" << sname << ",offset=" << hex << files[i].get_offset() << ",size=" << files[i].get_size() << dec << endl; cout << "sig1=" << dump(sig1) << ",sig2=" << dump(sig2) << ",mark=" << dump(mark) << ",mock=" << dump(xx) << endl; } if (argc > 2) { string destdir = argv[2]; mkdir(destdir.c_str(), 0755); int bufsize = 0; char *buf = NULL; char *unbuf = NULL; int unbufsize = 0; for (int i=0; i<filecount; i++) { File &frec = files[i]; lseek(f, frec.get_offset(), SEEK_SET); if (frec.get_size() > bufsize) { if (buf) delete []buf; buf = new char[frec.get_size()]; } int cnt = read(f, buf, frec.get_size()); if (cnt != frec.get_size()) { cerr << "warning: partial read for " << frec.get_name() << " " << cnt << " instead of " << frec.get_size() << " errno " << errno << endl; } string destpath = destdir + "/" + frec.get_name(); int outf = open(destpath.c_str(), O_WRONLY | O_CREAT, 0644); if (outf < 0) { cerr << "failed to open output file for " << destpath << " : " << errno << endl; } else { cout << "writing to " << destpath << " size: " << cnt << endl; write(outf, buf, cnt); close(outf); } } } } </source> 7af486912f69ff6d28a8082756099c84d094a83d 113 106 2012-01-10T21:19:17Z HenryHu 1 wikitext text/x-wiki 某文件格式 == 文件头 == Endian: Little Endian <source lang="asm"> 0x0000 Signature: AFS\0 0x0004 31 01 00 00 -> 0x131 = 305: record count 0x0008 00 10 00 00 -> 1st start: 0x1000 0x000C 7F 13 00 00 -> 1st size: 0x137F 0x0010 00 28 00 00 -> 2nd start: 0x2800 0x0014 B8 3D 00 00 -> 2nd size: 0x3DB8 .... </source> 最后一组之后:可能有文件索引的start & size,也可能没有…… 替代方法:从最后一个末尾往后找第一个非0的地方…… == 文件索引 == 在文件末尾,索引项大小: 0x30 = 48字节 <source lang="asm"> 1st record: 0x2C6000 BAD.BIP 00..00 0x2C6020 D9 07 08 00 -> 不明,包内相同,解包无关 0x2C6024 0D 00 0A 00 -> 不明,包内相同,解包无关,0D 0A好像不是那个意思…… 0x2C6028 06 00 20 00 -> 不明,多数递增00 00 02 00,也有不变/突变的情况,解包无关 0x2C602C 31 01 00 00 305 -> file count 貌似是垃圾字段,或者是文件头重复…… 2nd record: 0x2C6030 KA01.BIP 00..00 0x2C6050 D9 07 08 00 0x2C6054 0D 00 0A 00 0x2C6058 06 00 22 00 0x2C605C 00 10 00 00 4096 -> 1st start 3rd record: 0x2C6060 KA02.BIP 00..00 0x2C6080 D9 07 08 00 0x2C6080 0D 00 0A 00 0x2C6080 06 00 24 00 0x2C6080 7F 13 00 00 4991 -> 1st size Last record @ 0x2C9900 Total: 305 = 0x131 records </source> == 文件块 == 貌似先存的是索引里的偶数文件,跳过了第一个…… 反正一样解 <source lang="asm"> Last file start @ 2C5800 -> Guess: Min block size: 0x200 = 512 bytes 1st / 2nd start @ 0x1000 -? 0x237F size: 0x137F -> KA02.BIP next start @ 0x2800 diff: 0x4000 -? 0x65B8 size: 0x3DB8 -> KA04.BIP next start @ 0x6800 diff: 0x4000 size: 0xC63C -> KA06.BIP next start @ 0xA800 size: 0x379C -> KA08.BIP next start @ 0xE000 -? 0x1335A size: 0x535A diff: 0x5800 -> KAO.BIP next start @ 0x13800 </source> 貌似是用了[[LZSS]]压缩的,块前四字节是原大小,之后是[[LZSS]]压缩结果。大概是0x200对齐,末尾0填充。 == 分析过程 == <pre> mac.afs: found records @ tail 1st filename @ 2C6000 2nd filename @ 2C6030 3rd filename @ 2C6060 -> file record: 0x30 = 48 bytes 1st record: 0x2C6000 BAD.BIP 00..00 0x2C6020 D9 07 08 00 0x2C6024 0D 00 0A 00 0x2C6028 06 00 20 00 -> + 00 00 02 00 0x2C602C 31 01 00 00 305 -> file count? 2nd record: 0x2C6030 KA01.BIP 00..00 0x2C6050 D9 07 08 00 -> static 0x2C6054 0D 00 0A 00 -> static 0x2C6058 06 00 22 00 -> increasing ? 0x2C605C 00 10 00 00 4096 -> 1st start 3rd record: 0x2C6060 KA02.BIP 00..00 0x2C6080 D9 07 08 00 0x2C6080 0D 00 0A 00 0x2C6080 06 00 24 00 0x2C6080 7F 13 00 00 4991 -> 1st size Last record @ 0x2C9900 Total: 305 = 0x131 records Last file start @ 2C5800 -> Min block size: 0x200 = 512 bytes 1st / 2nd start @ 0x1000 -? 0x237F size: 0x137F -> KA02.BIP next start @ 0x2800 diff: 0x4000 -? 0x65B8 size: 0x3DB8 -> KA04.BIP next start @ 0x6800 diff: 0x4000 size: 0xC63C -> KA06.BIP next start @ 0xA800 size: 0x379C -> KA08.BIP next start @ 0xE000 -? 0x1335A size: 0x535A diff: 0x5800 -> KAO.BIP next start @ 0x13800 diff: Header: 0x00 AFS\0 0x0004 31 01 00 00 -> 0x131 = 305: record count 0x0008 00 10 00 00 -> 1st start 0x000C 7F 13 00 00 -> 1st size 0001000: 0823 0000 ff09 0f06 0000 6008 005f 0900 .#........`.._.. 0001010: 0860 fff5 f009 f9f0 ff4c 008c 0012 0319 .`.......L...... 0001020: 00ff 1a00 6580 0100 65a0 ff01 0033 0100 ....e...e....3.. 0001030: 01ff 10bb 3510 e8f3 6400 02eb f0c0 8fff ....5...d....... 0001040: 1e00 0f2b 0231 0fea f165 ff02 5a00 6520 ...+.1...e..Z.e 0x0010 00 28 00 00 -> 2nd start 0x0014 B8 3D 00 00 -> 2nd size 0002800: 0c6d 0000 ff09 0f06 0000 6008 00ff 1203 .m........`..... 0002810: 1900 1a00 6580 ff1e 0065 a001 0033 01bf ....e....e...3.. 0002820: 0001 ff10 0010 e8f3 65ff 0201 0065 2001 ........e....e . 0002830: 0009 ef00 0860 0a19 0009 6014 b619 0001 .....`....`..... 0002840: a0ec f000 0229 0203 be29 021a 6000 004c .....)...)..`..L 0x0018 00 68 00 00 -> 3rd start 0x001C C6 3C 00 00 -> 3rd size 0006800: 6367 0000 ff09 0f06 0000 6008 00df 0900 cg........`..... 0006810: 0860 0af5 f009 60ff 1900 4c00 4f00 5300 .`....`...L.O.S. 0006820: ff74 1065 8001 0065 a0ff 0100 3301 0001 .t.e...e....3... 0006830: ff10 bb4f 10e8 f364 0002 ebf0 c08f ff2d ...O...d.......- 0006840: 000f 2902 2f0f eaf1 41ff 043f 0340 003e ..)./...A..?.@.> 0x0020 00 A8 00 00 -> 4th start 0x0024 9C 37 00 00 -> 4th size 000a800: b163 0000 ff09 0f06 0000 6008 00df 0900 .c........`..... 000a810: 0860 0af5 f009 60ff 1b00 4c00 5200 5300 .`....`...L.R.S. 000a820: ff70 1065 8001 0065 a0ff 0100 3301 0001 .p.e...e....3... 000a830: ff10 fb0a 10e8 f341 043f 0340 ff00 3e00 .......A.?.@..>. 000a840: 3b80 3c80 3bff 8039 033a 0038 000f ff00 ;.<.;..9.:.8.... 0x0028 00 E0 00 00 -> 5th start 0x002C 5A 53 00 00 -> 5th size 0x0030 00 38 01 00 -> 6th start </pre> 于是可以解出来 但是貌似多数文件都压缩了…… * ADX = Ogg * BIP: Many possible formats... * T2P: Image, ... Update: 其实都是标准的[[LZSS]]压缩,只是我原来不知道还有那么些恶心的地方,于是搞了好久…… 图片都是TIM2格式,据说是PS2的?里面包着奇怪的东西,多数是原封不动的PNG BIP有些是脚本,格式还不清楚,反正最后有字符串库,前面不知道是啥…… == 解包代码 == unlzss.cpp <source lang="cpp"> #include <iostream> #include <fcntl.h> #include <vector> #include <string> #include <sys/endian.h> #include <errno.h> #include <sys/stat.h> #include <zlib.h> using namespace std; typedef unsigned char uchar; string dump(unsigned char *data) { char buf[20]; snprintf(buf, 20, "%02x %02x %02x %02x", data[0], data[1], data[2], data[3]); return string(buf); } void toh(uint32_t &x) { x = le32toh(x); } class File { int size, offset; uchar sig1[4], sig2[4], mark[4], xx[4]; string name; public: File(int _offset, int _size) : size(_size), offset(_offset) {} int get_size() { return size; } int get_offset() { return offset; } const string & get_name() { return name; } void set_info(const string& _name, uchar *_sig1, uchar *_sig2, uchar *_mark, uchar *_xx) { name = _name; memcpy(sig1, _sig1, 4); memcpy(sig2, _sig1, 4); memcpy(mark, _mark, 4); memcpy(xx, _xx, 4); } }; int main(int argc, char **argv) { if (argc < 2) { cout << "usage: " << argv[0] << " <afs file> [<output dir>]" << endl; return -1; } char head[4]; int f = open(argv[1], O_RDONLY); if (f < 0) { cout << "fail to open file: " << errno << endl; return -2; } read(f, head, 4); if (memcmp(head, "AFS\0", 4) != 0) { cout << "signature mismatch!\n" << endl; close(f); return 1; } vector<File> files; uint32_t filecount; read(f, &filecount, 4); filecount = le32toh(filecount); cout << "file count: " << filecount << endl; // last file: directory for (int i=0; i<filecount+1; i++) { uint32_t offset, size; read(f, &offset, 4); read(f, &size, 4); toh(offset); toh(size); if ((size == 0) && (i == filecount)) { // ugly state: no last record int x = files[i-1].get_offset() + files[i-1].get_size() + 1; lseek(f, x, SEEK_SET); char ch; read(f, &ch, 1); while (ch == 0) { read(f, &ch, 1); x++; } offset = x; size = 0x30 * filecount; } files.push_back(File(offset, size)); // cout << "File " << i << ": offset=" << hex << files[i].get_offset() << ",size=" << size << "#" << dec << size << dec << endl; } for (int i=0; i<filecount; i++) { lseek(f, files[filecount].get_offset() + 0x30 * i, SEEK_SET); char name[33]; name[32] = '\0'; read(f, name, 32); string sname(name); unsigned char sig1[4]; unsigned char sig2[4]; read(f, sig1, 4); read(f, sig2, 4); unsigned char mark[4]; read(f, mark, 4); unsigned char xx[4]; read(f, xx, 4); files[i].set_info(sname, sig1, sig2, mark, xx); cout << "File " << i << ": name=" << sname << ",offset=" << hex << files[i].get_offset() << ",size=" << files[i].get_size() << dec << endl; cout << "sig1=" << dump(sig1) << ",sig2=" << dump(sig2) << ",mark=" << dump(mark) << ",mock=" << dump(xx) << endl; } if (argc > 2) { string destdir = argv[2]; mkdir(destdir.c_str(), 0755); int bufsize = 0; char *buf = NULL; char *unbuf = NULL; int unbufsize = 0; for (int i=0; i<filecount; i++) { File &frec = files[i]; lseek(f, frec.get_offset(), SEEK_SET); if (frec.get_size() > bufsize) { if (buf) delete []buf; buf = new char[frec.get_size()]; } int cnt = read(f, buf, frec.get_size()); if (cnt != frec.get_size()) { cerr << "warning: partial read for " << frec.get_name() << " " << cnt << " instead of " << frec.get_size() << " errno " << errno << endl; } string destpath = destdir + "/" + frec.get_name(); int outf = open(destpath.c_str(), O_WRONLY | O_CREAT, 0644); if (outf < 0) { cerr << "failed to open output file for " << destpath << " : " << errno << endl; } else { cout << "writing to " << destpath << " size: " << cnt << endl; write(outf, buf, cnt); close(outf); } } } } </source> 95329864480ac33c7ab6505762d84bb1474ea11c LZSS 0 43 107 2012-01-09T22:57:49Z HenryHu 1 以内容“Lempel–Ziv–Storer–Szymanski 一种压缩算法 每八个东西前有个字节标记这8个是啥。对应位是1的话,就是原来的字节。对应位是0...”创建新页面 wikitext text/x-wiki Lempel–Ziv–Storer–Szymanski 一种压缩算法 每八个东西前有个字节标记这8个是啥。对应位是1的话,就是原来的字节。对应位是0,则这个东西占俩字节,引用窗口里的一段东西。 == 标准LZSS算法 == 初始窗口指针=0xFEE // 恶心! 初始窗口清空。 读标记 对每一位: 1->原样输出一个字节,附加到窗口之后。 0->读俩字节,取第二字节高四位拼上第一个字节作为窗口内开始位置,第二字节低四位+3(0,1,2不可能……)作为长度,输出窗口内容,同时也附加到窗口之后。 == 变种 == 取第一字节拼上第二字节高'''三'''位作为窗口内开始位置,第二字节低'''五'''位+'''2'''作为长度 == 代码 == <source lang="cpp"> #include <fcntl.h> #include <iostream> #include <errno.h> #include <stdlib.h> #include <stdio.h> #include <string.h> using namespace std; string dump(char ch) { char buf[3]; snprintf(buf, 3, "%02x", (unsigned char)ch); return string(buf); } string dumpb(char ch) { char buf[10]; buf[8] = 0; for (int i=0; i<8; i++) if (ch & (1 << i)) buf[7-i] = '1'; else buf[7-i] = '0'; return string(buf); } int uncompress(int fin, int fout, int from_bits) { // example: // from_bits = 3 // len_mask = 0x1f : 0001 1111 // from_mask = 0xe0 : 1110 0000 // ^^^ 3 int window_size = 0x100 << from_bits; unsigned char len_mask = (1 << (8 - from_bits)) - 1; unsigned char from_mask = 0xFF - len_mask; cout << hex << window_size << dec << '/' << dump(len_mask) << '/' << dump(from_mask) << endl; char window[window_size]; int win_pos = from_bits == 4 ? 0xFEE : 0; int out_len = 0; int in_len = 0; int br_cnt = 0; memset(window, 0, window_size); while (true) { char flag; int cnt = read(fin, &flag, 1); if (cnt == 0) break; int index = 0; for (int index = 0; index < 8; index++, flag >>= 1) { if (flag & 1) { out_len++; char ch; cnt = read(fin, &ch, 1); if (cnt == 0) break; write(fout, &ch, 1); window[win_pos] = ch; win_pos = (win_pos + 1) % window_size; // cout << dump(ch) << " "; // if (isprint(ch)) // cout << ch << ' '; in_len++; } else { br_cnt++; unsigned char lead, offset; cnt = read(fin, &offset, 1); if (cnt == 0) break; cnt = read(fin, &lead, 1); if (cnt == 0) break; // cout << endl << "backref: pos=" << hex << in_len << ", dpos=" << out_len << ", lead=" << hex << (int)lead << ", offset=" << (int)offset << dec << '\t' << dumpb(lead) << "/" << dumpb(offset) << endl; int copy_len = (lead & len_mask) + 3; int copy_from = ((lead & from_mask) << from_bits) | (offset & 0xff); // cout << "backref: len=" << hex << copy_len << ", from=" << copy_from << dec << endl; for (int i=0; i<copy_len; i++) { int ret = write(fout, &window[copy_from], 1); if (ret != 1) cerr << "writeout failed! " << errno << endl; window[win_pos] = window[copy_from]; copy_from = (copy_from + 1) % window_size; win_pos = (win_pos + 1) % window_size; } out_len += copy_len; in_len += 2; } } if (cnt == 0) break; } return out_len; } int main(int argc, char **argv) { if (argc < 3) { cerr << "usage: " << argv[0] << " <infile> <outfile> [<skip>]" << endl; return 1; } int fin = open(argv[1], O_RDONLY); int fout = open(argv[2], O_WRONLY | O_CREAT, 0644); if ((fin < 0) || (fout < 0)) { cerr << "file open error! " << errno << endl; return errno; } if (argc > 3) { int skip = atoi(argv[3]); char buf[1024]; while (skip > 0) { int cnt = read(fin, buf, skip > 1024 ? 1024 : skip); if (cnt <= 0) { cerr << "skip error! " << errno << endl; return 3; } skip -= cnt; } } int from_bits = 4; if (argc > 4) from_bits = atoi(argv[4]); int out_len = uncompress(fin, fout, from_bits); cout << "result len: " << out_len << endl; close(fin); close(fout); } </source> 220870564a30f0ad9b97a2e4f688c16fc6fa2655 108 107 2012-01-09T22:58:19Z HenryHu 1 /* 变种 */ wikitext text/x-wiki Lempel–Ziv–Storer–Szymanski 一种压缩算法 每八个东西前有个字节标记这8个是啥。对应位是1的话,就是原来的字节。对应位是0,则这个东西占俩字节,引用窗口里的一段东西。 == 标准LZSS算法 == 初始窗口指针=0xFEE // 恶心! 初始窗口清空。 读标记 对每一位: 1->原样输出一个字节,附加到窗口之后。 0->读俩字节,取第二字节高四位拼上第一个字节作为窗口内开始位置,第二字节低四位+3(0,1,2不可能……)作为长度,输出窗口内容,同时也附加到窗口之后。 == 变种 == * 取第一字节拼上第二字节高'''三'''位作为窗口内开始位置,第二字节低'''五'''位+'''2'''作为长度,窗口大小0x800 == 代码 == <source lang="cpp"> #include <fcntl.h> #include <iostream> #include <errno.h> #include <stdlib.h> #include <stdio.h> #include <string.h> using namespace std; string dump(char ch) { char buf[3]; snprintf(buf, 3, "%02x", (unsigned char)ch); return string(buf); } string dumpb(char ch) { char buf[10]; buf[8] = 0; for (int i=0; i<8; i++) if (ch & (1 << i)) buf[7-i] = '1'; else buf[7-i] = '0'; return string(buf); } int uncompress(int fin, int fout, int from_bits) { // example: // from_bits = 3 // len_mask = 0x1f : 0001 1111 // from_mask = 0xe0 : 1110 0000 // ^^^ 3 int window_size = 0x100 << from_bits; unsigned char len_mask = (1 << (8 - from_bits)) - 1; unsigned char from_mask = 0xFF - len_mask; cout << hex << window_size << dec << '/' << dump(len_mask) << '/' << dump(from_mask) << endl; char window[window_size]; int win_pos = from_bits == 4 ? 0xFEE : 0; int out_len = 0; int in_len = 0; int br_cnt = 0; memset(window, 0, window_size); while (true) { char flag; int cnt = read(fin, &flag, 1); if (cnt == 0) break; int index = 0; for (int index = 0; index < 8; index++, flag >>= 1) { if (flag & 1) { out_len++; char ch; cnt = read(fin, &ch, 1); if (cnt == 0) break; write(fout, &ch, 1); window[win_pos] = ch; win_pos = (win_pos + 1) % window_size; // cout << dump(ch) << " "; // if (isprint(ch)) // cout << ch << ' '; in_len++; } else { br_cnt++; unsigned char lead, offset; cnt = read(fin, &offset, 1); if (cnt == 0) break; cnt = read(fin, &lead, 1); if (cnt == 0) break; // cout << endl << "backref: pos=" << hex << in_len << ", dpos=" << out_len << ", lead=" << hex << (int)lead << ", offset=" << (int)offset << dec << '\t' << dumpb(lead) << "/" << dumpb(offset) << endl; int copy_len = (lead & len_mask) + 3; int copy_from = ((lead & from_mask) << from_bits) | (offset & 0xff); // cout << "backref: len=" << hex << copy_len << ", from=" << copy_from << dec << endl; for (int i=0; i<copy_len; i++) { int ret = write(fout, &window[copy_from], 1); if (ret != 1) cerr << "writeout failed! " << errno << endl; window[win_pos] = window[copy_from]; copy_from = (copy_from + 1) % window_size; win_pos = (win_pos + 1) % window_size; } out_len += copy_len; in_len += 2; } } if (cnt == 0) break; } return out_len; } int main(int argc, char **argv) { if (argc < 3) { cerr << "usage: " << argv[0] << " <infile> <outfile> [<skip>]" << endl; return 1; } int fin = open(argv[1], O_RDONLY); int fout = open(argv[2], O_WRONLY | O_CREAT, 0644); if ((fin < 0) || (fout < 0)) { cerr << "file open error! " << errno << endl; return errno; } if (argc > 3) { int skip = atoi(argv[3]); char buf[1024]; while (skip > 0) { int cnt = read(fin, buf, skip > 1024 ? 1024 : skip); if (cnt <= 0) { cerr << "skip error! " << errno << endl; return 3; } skip -= cnt; } } int from_bits = 4; if (argc > 4) from_bits = atoi(argv[4]); int out_len = uncompress(fin, fout, from_bits); cout << "result len: " << out_len << endl; close(fin); close(fout); } </source> 2b473a60eea7612dfc613c733448588ac1cbc2e5 109 108 2012-01-09T22:58:31Z HenryHu 1 /* 标准LZSS算法 */ wikitext text/x-wiki Lempel–Ziv–Storer–Szymanski 一种压缩算法 每八个东西前有个字节标记这8个是啥。对应位是1的话,就是原来的字节。对应位是0,则这个东西占俩字节,引用窗口里的一段东西。 == 标准LZSS算法 == 初始窗口指针=0xFEE // 恶心! 初始窗口清空。 读标记 对每一位: 1->原样输出一个字节,附加到窗口之后。 0->读俩字节,取第二字节高四位拼上第一个字节作为窗口内开始位置,第二字节低四位+3(0,1,2不可能……)作为长度,输出窗口内容,同时也附加到窗口之后。 窗口大小0x1000 == 变种 == * 取第一字节拼上第二字节高'''三'''位作为窗口内开始位置,第二字节低'''五'''位+'''2'''作为长度,窗口大小0x800 == 代码 == <source lang="cpp"> #include <fcntl.h> #include <iostream> #include <errno.h> #include <stdlib.h> #include <stdio.h> #include <string.h> using namespace std; string dump(char ch) { char buf[3]; snprintf(buf, 3, "%02x", (unsigned char)ch); return string(buf); } string dumpb(char ch) { char buf[10]; buf[8] = 0; for (int i=0; i<8; i++) if (ch & (1 << i)) buf[7-i] = '1'; else buf[7-i] = '0'; return string(buf); } int uncompress(int fin, int fout, int from_bits) { // example: // from_bits = 3 // len_mask = 0x1f : 0001 1111 // from_mask = 0xe0 : 1110 0000 // ^^^ 3 int window_size = 0x100 << from_bits; unsigned char len_mask = (1 << (8 - from_bits)) - 1; unsigned char from_mask = 0xFF - len_mask; cout << hex << window_size << dec << '/' << dump(len_mask) << '/' << dump(from_mask) << endl; char window[window_size]; int win_pos = from_bits == 4 ? 0xFEE : 0; int out_len = 0; int in_len = 0; int br_cnt = 0; memset(window, 0, window_size); while (true) { char flag; int cnt = read(fin, &flag, 1); if (cnt == 0) break; int index = 0; for (int index = 0; index < 8; index++, flag >>= 1) { if (flag & 1) { out_len++; char ch; cnt = read(fin, &ch, 1); if (cnt == 0) break; write(fout, &ch, 1); window[win_pos] = ch; win_pos = (win_pos + 1) % window_size; // cout << dump(ch) << " "; // if (isprint(ch)) // cout << ch << ' '; in_len++; } else { br_cnt++; unsigned char lead, offset; cnt = read(fin, &offset, 1); if (cnt == 0) break; cnt = read(fin, &lead, 1); if (cnt == 0) break; // cout << endl << "backref: pos=" << hex << in_len << ", dpos=" << out_len << ", lead=" << hex << (int)lead << ", offset=" << (int)offset << dec << '\t' << dumpb(lead) << "/" << dumpb(offset) << endl; int copy_len = (lead & len_mask) + 3; int copy_from = ((lead & from_mask) << from_bits) | (offset & 0xff); // cout << "backref: len=" << hex << copy_len << ", from=" << copy_from << dec << endl; for (int i=0; i<copy_len; i++) { int ret = write(fout, &window[copy_from], 1); if (ret != 1) cerr << "writeout failed! " << errno << endl; window[win_pos] = window[copy_from]; copy_from = (copy_from + 1) % window_size; win_pos = (win_pos + 1) % window_size; } out_len += copy_len; in_len += 2; } } if (cnt == 0) break; } return out_len; } int main(int argc, char **argv) { if (argc < 3) { cerr << "usage: " << argv[0] << " <infile> <outfile> [<skip>]" << endl; return 1; } int fin = open(argv[1], O_RDONLY); int fout = open(argv[2], O_WRONLY | O_CREAT, 0644); if ((fin < 0) || (fout < 0)) { cerr << "file open error! " << errno << endl; return errno; } if (argc > 3) { int skip = atoi(argv[3]); char buf[1024]; while (skip > 0) { int cnt = read(fin, buf, skip > 1024 ? 1024 : skip); if (cnt <= 0) { cerr << "skip error! " << errno << endl; return 3; } skip -= cnt; } } int from_bits = 4; if (argc > 4) from_bits = atoi(argv[4]); int out_len = uncompress(fin, fout, from_bits); cout << "result len: " << out_len << endl; close(fin); close(fout); } </source> 77b015c2cddb4d6e555c24d265f9bd0db8417386 111 109 2012-01-10T02:23:04Z HenryHu 1 /* 代码 */ wikitext text/x-wiki Lempel–Ziv–Storer–Szymanski 一种压缩算法 每八个东西前有个字节标记这8个是啥。对应位是1的话,就是原来的字节。对应位是0,则这个东西占俩字节,引用窗口里的一段东西。 == 标准LZSS算法 == 初始窗口指针=0xFEE // 恶心! 初始窗口清空。 读标记 对每一位: 1->原样输出一个字节,附加到窗口之后。 0->读俩字节,取第二字节高四位拼上第一个字节作为窗口内开始位置,第二字节低四位+3(0,1,2不可能……)作为长度,输出窗口内容,同时也附加到窗口之后。 窗口大小0x1000 == 变种 == * 取第一字节拼上第二字节高'''三'''位作为窗口内开始位置,第二字节低'''五'''位+'''2'''作为长度,窗口大小0x800 == revision == 第一版用的read和write,系统调用占了大部分时间…… 现在用fread和fwrite了 == 代码 == <source lang="cpp"> #include <fcntl.h> #include <iostream> #include <errno.h> #include <stdlib.h> #include <stdio.h> #include <string.h> using namespace std; int get_char(FILE *f, unsigned char *ch) { int cnt = fread(ch, 1, 1, f); return cnt; } int put_char(FILE *f, unsigned char *ch) { int cnt = fwrite(ch, 1, 1, f); return cnt; } string dump(char ch) { char buf[3]; snprintf(buf, 3, "%02x", (unsigned char)ch); return string(buf); } string dumpb(char ch) { char buf[10]; buf[8] = 0; for (int i=0; i<8; i++) if (ch & (1 << i)) buf[7-i] = '1'; else buf[7-i] = '0'; return string(buf); } int uncompress(FILE* fin, FILE* fout, int from_bits) { // example: // from_bits = 3 // len_mask = 0x1f : 0001 1111 // from_mask = 0xe0 : 1110 0000 // ^^^ 3 int window_size = 0x100 << from_bits; unsigned char len_mask = (1 << (8 - from_bits)) - 1; unsigned char from_mask = 0xFF - len_mask; // cout << hex << window_size << dec << '/' << dump(len_mask) << '/' << dump(from_mask) << endl; unsigned char window[window_size]; int win_pos = from_bits == 4 ? 0xFEE : 0; int out_len = 0; int in_len = 0; int br_cnt = 0; memset(window, 0, window_size); unsigned char xbuf[8]; while (true) { unsigned char flag; int cnt = get_char(fin, &flag); if (cnt == 0) break; int index = 0; /* if (flag == 0xff) { cnt = 0; for (int i=0; i<8; i++) { cnt += get_char(fin, &xbuf[i]); } write(fout, xbuf, cnt); for (int i=0; i<cnt; i++) window[win_pos++] = xbuf[i]; in_len+=8; out_len+=8; continue; }*/ for (int index = 0; index < 8; index++, flag >>= 1) { if (flag & 1) { out_len++; unsigned char ch; cnt = get_char(fin, &ch); if (cnt == 0) break; put_char(fout, &ch); window[win_pos] = ch; win_pos = (win_pos + 1) % window_size; // cout << dump(ch) << " "; // if (isprint(ch)) // cout << ch << ' '; in_len++; } else { br_cnt++; unsigned char lead, offset; cnt = get_char(fin, &offset); if (cnt == 0) break; cnt = get_char(fin, &lead); if (cnt == 0) break; // cout << endl << "backref: pos=" << hex << in_len << ", dpos=" << out_len << ", lead=" << hex << (int)lead << ", offset=" << (int)offset << dec << '\t' << dumpb(lead) << "/" << dumpb(offset) << endl; int copy_len = (lead & len_mask) + 3; int copy_from = ((lead & from_mask) << from_bits) | (offset & 0xff); // cout << "backref: len=" << hex << copy_len << ", from=" << copy_from << dec << endl; for (int i=0; i<copy_len; i++) { int ret = put_char(fout, &window[copy_from]); if (ret != 1) cerr << "writeout failed! " << errno << endl; window[win_pos] = window[copy_from]; copy_from = (copy_from + 1) % window_size; win_pos = (win_pos + 1) % window_size; } out_len += copy_len; in_len += 2; } } if (cnt == 0) break; } return out_len; } int main(int argc, char **argv) { if (argc < 3) { cerr << "usage: " << argv[0] << " <infile> <outfile> [<skip>]" << endl; return 1; } FILE * fin = fopen(argv[1], "rb"); FILE * fout = fopen(argv[2], "wb"); if (fin == NULL || fout == NULL) { cerr << "file open error! " << errno << endl; return errno; } if (argc > 3) { int skip = atoi(argv[3]); char buf[1024]; while (skip > 0) { int cnt = fread(buf, 1, skip > 1024 ? 1024 : skip, fin); if (cnt <= 0) { cerr << "skip error! " << errno << endl; return 3; } skip -= cnt; } } int from_bits = 4; if (argc > 4) from_bits = atoi(argv[4]); int out_len = uncompress(fin, fout, from_bits); cout << "result len: " << out_len << endl; fclose(fin); fclose(fout); } </source> 90dd50cf6667663c97ed46a49e6338fba944e502 112 111 2012-01-10T02:25:06Z HenryHu 1 /* 代码 */ wikitext text/x-wiki Lempel–Ziv–Storer–Szymanski 一种压缩算法 每八个东西前有个字节标记这8个是啥。对应位是1的话,就是原来的字节。对应位是0,则这个东西占俩字节,引用窗口里的一段东西。 == 标准LZSS算法 == 初始窗口指针=0xFEE // 恶心! 初始窗口清空。 读标记 对每一位: 1->原样输出一个字节,附加到窗口之后。 0->读俩字节,取第二字节高四位拼上第一个字节作为窗口内开始位置,第二字节低四位+3(0,1,2不可能……)作为长度,输出窗口内容,同时也附加到窗口之后。 窗口大小0x1000 == 变种 == * 取第一字节拼上第二字节高'''三'''位作为窗口内开始位置,第二字节低'''五'''位+'''2'''作为长度,窗口大小0x800 == revision == 第一版用的read和write,系统调用占了大部分时间…… 现在用fread和fwrite了 == 代码 == <source lang="cpp"> #include <fcntl.h> #include <iostream> #include <errno.h> #include <stdlib.h> #include <stdio.h> #include <string.h> using namespace std; int get_char(FILE *f, unsigned char *ch) { int cnt = fread(ch, 1, 1, f); return cnt; } int put_char(FILE *f, unsigned char *ch) { int cnt = fwrite(ch, 1, 1, f); return cnt; } string dump(char ch) { char buf[3]; snprintf(buf, 3, "%02x", (unsigned char)ch); return string(buf); } string dumpb(char ch) { char buf[10]; buf[8] = 0; for (int i=0; i<8; i++) if (ch & (1 << i)) buf[7-i] = '1'; else buf[7-i] = '0'; return string(buf); } int uncompress(FILE* fin, FILE* fout, int from_bits) { // example: // from_bits = 3 // len_mask = 0x1f : 0001 1111 // from_mask = 0xe0 : 1110 0000 // ^^^ 3 int window_size = 0x100 << from_bits; unsigned char len_mask = (1 << (8 - from_bits)) - 1; unsigned char from_mask = 0xFF - len_mask; // cout << hex << window_size << dec << '/' << dump(len_mask) << '/' << dump(from_mask) << endl; unsigned char window[window_size]; int win_pos = from_bits == 4 ? 0xFEE : 0; int out_len = 0; int in_len = 0; int br_cnt = 0; memset(window, 0, window_size); unsigned char xbuf[8]; while (true) { unsigned char flag; int cnt = get_char(fin, &flag); if (cnt == 0) break; int index = 0; for (int index = 0; index < 8; index++, flag >>= 1) { if (flag & 1) { out_len++; unsigned char ch; cnt = get_char(fin, &ch); if (cnt == 0) break; put_char(fout, &ch); window[win_pos] = ch; win_pos = (win_pos + 1) % window_size; // cout << dump(ch) << " "; // if (isprint(ch)) // cout << ch << ' '; in_len++; } else { br_cnt++; unsigned char lead, offset; cnt = get_char(fin, &offset); if (cnt == 0) break; cnt = get_char(fin, &lead); if (cnt == 0) break; // cout << endl << "backref: pos=" << hex << in_len << ", dpos=" << out_len << ", lead=" << hex << (int)lead << ", offset=" << (int)offset << dec << '\t' << dumpb(lead) << "/" << dumpb(offset) << endl; int copy_len = (lead & len_mask) + 3; int copy_from = ((lead & from_mask) << from_bits) | (offset & 0xff); // cout << "backref: len=" << hex << copy_len << ", from=" << copy_from << dec << endl; for (int i=0; i<copy_len; i++) { int ret = put_char(fout, &window[copy_from]); if (ret != 1) cerr << "writeout failed! " << errno << endl; window[win_pos] = window[copy_from]; copy_from = (copy_from + 1) % window_size; win_pos = (win_pos + 1) % window_size; } out_len += copy_len; in_len += 2; } } if (cnt == 0) break; } return out_len; } int main(int argc, char **argv) { if (argc < 3) { cerr << "usage: " << argv[0] << " <infile> <outfile> [<skip>]" << endl; return 1; } FILE * fin = fopen(argv[1], "rb"); FILE * fout = fopen(argv[2], "wb"); if (fin == NULL || fout == NULL) { cerr << "file open error! " << errno << endl; return errno; } if (argc > 3) { int skip = atoi(argv[3]); char buf[1024]; while (skip > 0) { int cnt = fread(buf, 1, skip > 1024 ? 1024 : skip, fin); if (cnt <= 0) { cerr << "skip error! " << errno << endl; return 3; } skip -= cnt; } } int from_bits = 4; if (argc > 4) from_bits = atoi(argv[4]); int out_len = uncompress(fin, fout, from_bits); cout << "result len: " << out_len << endl; fclose(fin); fclose(fout); } </source> 8bdb849171b0f4b694b0a8486523e284a084d43c Zlib 0 44 110 2012-01-10T01:01:23Z HenryHu 1 以内容“== 解压 == 源自zlib官网代码 <source lang="cpp"> int uncompress(char *buf, int size, char *newbuf, int newsize) { int ret; z_stream strm; /* alloca...”创建新页面 wikitext text/x-wiki == 解压 == 源自zlib官网代码 <source lang="cpp"> int uncompress(char *buf, int size, char *newbuf, int newsize) { int ret; z_stream strm; /* allocate inflate state */ strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = 0; strm.next_in = Z_NULL; ret = inflateInit(&strm); if (ret != Z_OK) return ret; /* decompress until deflate stream ends or end of file */ strm.avail_in = size; strm.next_in = (Bytef *)buf; /* run inflate() on input until output buffer not full */ strm.avail_out = newsize; strm.next_out = (Bytef *)newbuf; ret = inflate(&strm, Z_NO_FLUSH); if(ret == Z_STREAM_ERROR) /* state not clobbered */ return ret; switch (ret) { case Z_NEED_DICT: ret = Z_DATA_ERROR; /* and fall through */ case Z_DATA_ERROR: case Z_MEM_ERROR: (void)inflateEnd(&strm); return ret; } /* done when inflate() says it's done */ /* clean up and return */ (void)inflateEnd(&strm); return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; } </source> ce0021e3661d4cb7680d8d8f2b49198a0331f04a 韭菜炒肉 0 45 115 2012-01-27T02:30:37Z HenryHu 1 以内容“来源: [http://www.meishij.net/jiangchangcaipu/jiucairousi.html 韭菜肉丝] == 原料 == * 肉 若干 * 韭菜 若干 == 配料 == * 盐 一些 == 准备 == ...”创建新页面 wikitext text/x-wiki 来源: [http://www.meishij.net/jiangchangcaipu/jiucairousi.html 韭菜肉丝] == 原料 == * 肉 若干 * 韭菜 若干 == 配料 == * 盐 一些 == 准备 == 韭菜切段。肉切丝,加酱油、淀粉、水,一起腌一会。 == 制作 == 锅热,加油。倒入肉,翻炒。(稍长一些,至少全部变色为止) 倒入韭菜,翻炒。 加少许盐,出锅。 34678cddf4c6a9c69eba49c116191d0812381fa8 116 115 2012-01-27T02:34:20Z HenryHu 1 /* 配料 */ wikitext text/x-wiki 来源: [http://www.meishij.net/jiangchangcaipu/jiucairousi.html 韭菜肉丝] == 原料 == * 肉 若干 * 韭菜 若干 == 配料 == * 盐 一些 * 酱油 一点 * 淀粉 少许 == 准备 == 韭菜切段。肉切丝,加酱油、淀粉、水,一起腌一会。 == 制作 == 锅热,加油。倒入肉,翻炒。(稍长一些,至少全部变色为止) 倒入韭菜,翻炒。 加少许盐,出锅。 48236ca8d793cd01cbc2becc9bcc99702c331554 韭菜炒蛋 0 46 117 2012-01-27T02:45:36Z HenryHu 1 以内容“来源: 多谢aqua指导示范! == 原料 == * 韭菜 若干 * 蛋 几个 == 配料 == * 盐 一些 * 酒 一点 == 准备 == 蛋打入碗中,加些许油...”创建新页面 wikitext text/x-wiki 来源: 多谢aqua指导示范! == 原料 == * 韭菜 若干 * 蛋 几个 == 配料 == * 盐 一些 * 酒 一点 == 准备 == 蛋打入碗中,加些许油,加一点酒,加些盐,混合均匀。 韭菜切小段,与蛋混合。 == 制作 == 锅热,加油。倒入混合物,翻炒。 出锅。 2addd7f7d0b83aa940aa0a0ee55364b0f3e4ec51 118 117 2012-01-27T02:47:19Z HenryHu 1 /* 准备 */ wikitext text/x-wiki 来源: 多谢aqua指导示范! == 原料 == * 韭菜 若干 * 蛋 几个 == 配料 == * 盐 一些 * 酒 一点 == 准备 == 蛋打入碗中,加些许油,加一点酒,加些盐,蛋打碎并混合均匀。 韭菜切小段,与蛋混合。 == 制作 == 锅热,加油。倒入混合物,翻炒。 出锅。 225da390461b3e3dccab0e3a5808fa0fb397f731 119 118 2012-01-27T02:47:29Z HenryHu 1 /* 准备 */ wikitext text/x-wiki 来源: 多谢aqua指导示范! == 原料 == * 韭菜 若干 * 蛋 几个 == 配料 == * 盐 一些 * 酒 一点 == 准备 == 蛋打入碗中,加些许油,加一点酒,加些盐。将蛋打碎并混合均匀。 韭菜切小段,与蛋混合。 == 制作 == 锅热,加油。倒入混合物,翻炒。 出锅。 ff649f534bf3bc3817ded00b517a53128a906f7a 炒土豆丝 0 47 121 2012-01-28T20:07:16Z HenryHu 1 以内容“来源:随便炒的…… == 原料 == * 土豆 几个 == 配料 == * 葱 一段 * 盐 一些 * 糖 一些 == 准备 == 土豆去皮,刨丝。葱切碎,放...”创建新页面 wikitext text/x-wiki 来源:随便炒的…… == 原料 == * 土豆 几个 == 配料 == * 葱 一段 * 盐 一些 * 糖 一些 == 准备 == 土豆去皮,刨丝。葱切碎,放入土豆丝中。 == 制作 == 锅热,放油。倒入土豆丝和葱。 翻炒,出锅。 93eddc084a4d1ee43c8cf3bf5194b77b33603841 122 121 2012-01-28T20:07:30Z HenryHu 1 /* 制作 */ wikitext text/x-wiki 来源:随便炒的…… == 原料 == * 土豆 几个 == 配料 == * 葱 一段 * 盐 一些 * 糖 一些 == 准备 == 土豆去皮,刨丝。葱切碎,放入土豆丝中。 == 制作 == 锅热,放油。倒入土豆丝和葱。 翻炒,加糖,加盐。 翻炒,出锅。 7476f6f1d2030c99ef38ba342f7a9385df2955e0 124 122 2012-01-28T20:53:49Z HenryHu 1 /* 准备 */ wikitext text/x-wiki 来源:随便炒的…… == 原料 == * 土豆 几个 == 配料 == * 葱 一段 * 盐 一些 * 糖 一些 == 准备 == 土豆去皮,刨丝。用水冲土豆丝直至水清澈。 葱切碎,放入土豆丝中。 == 制作 == 锅热,放油。倒入土豆丝和葱。 翻炒,加糖,加盐。 翻炒,出锅。 cd03866d219a0d8bf14e5514f242c84131111926 首页 0 1 123 97 2012-01-28T20:44:56Z HenryHu 1 wikitext text/x-wiki [[SubsConscious]] [[:Category:脚本|Scripts]] [[Package Management]] <!-- == 入门 == * [http://www.mediawiki.org/wiki/Manual:Configuration_settings MediaWiki 配置设置列表] * [http://www.mediawiki.org/wiki/Manual:FAQ/zh-hans MediaWiki常见问题] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki发布邮件列表] --> 8fd707387b342df41ee838d6e08fb25e22e58ba0 BBS 代码分析 0 48 125 2012-01-29T07:01:11Z HenryHu 1 以内容“为了搞出来的东西能和这套shit一样的代码配合工作,首先要研究这坨代码…… [[BBS 信息机制]] [[BBS 好友列表]] [[BBS 帖子]] [[BBS ...”创建新页面 wikitext text/x-wiki 为了搞出来的东西能和这套shit一样的代码配合工作,首先要研究这坨代码…… [[BBS 信息机制]] [[BBS 好友列表]] [[BBS 帖子]] [[BBS 用户信息]] [[BBS 帖子列表]] [[BBS 版面列表]] [[BBS 收藏夹]] [[BBS 信件]] [[BBS 会话]] f57b66d8999bcf0a7864636e121d211ecee48831 126 125 2012-01-29T07:01:34Z HenryHu 1 wikitext text/x-wiki 为了搞出来的东西能和这套shit一样的代码配合工作,首先要研究这坨代码…… * [[BBS 信息机制]] * [[BBS 好友列表]] * [[BBS 帖子]] * [[BBS 用户信息]] * [[BBS 帖子列表]] * [[BBS 版面列表]] * [[BBS 收藏夹]] * [[BBS 信件]] * [[BBS 会话]] b73afde9e4bb56de25220d5658d39d82308eb621 144 126 2012-02-01T04:04:23Z HenryHu 1 wikitext text/x-wiki 为了搞出来的东西能和这套shit一样的代码配合工作,首先要研究这坨代码…… * [[BBS 信息机制]] * [[BBS 好友列表]] * [[BBS 帖子]] * [[BBS 会话信息]] * [[BBS 用户信息]] * [[BBS 帖子列表]] * [[BBS 版面列表]] * [[BBS 收藏夹]] * [[BBS 信件]] f5124ae533f6fba6c7f70b748956f56ede9be50e BBS 信息机制 0 49 127 2012-01-29T07:41:03Z HenryHu 1 以内容“== 数据结构 == === 消息索引 === msgindex, msgindex2 * 0x00-0x03 4字节 * 之后:struct msghead[] == libmsg.c == === save_msgtext() === 把消息存...”创建新页面 wikitext text/x-wiki == 数据结构 == === 消息索引 === msgindex, msgindex2 * 0x00-0x03 4字节 * 之后:struct msghead[] == libmsg.c == === save_msgtext() === 把消息存到用户的msgindex与msgcontent文件中。如果是接收到的,也存到msgindex2中。 2690bb9609700ae22acab81637bb6154d7fd3ff1 128 127 2012-01-29T23:45:08Z HenryHu 1 wikitext text/x-wiki == 数据结构 == === 消息索引 === # msgindex:全消息箱 # msgindex2:收件箱 * 0x00-0x03 4字节 ** 对于收件箱:已读消息个数 * 之后:struct msghead[] == libmsg.c == # save_msgtext() * 对应 MsgBox.SaveMsgText() 把消息存到用户的msgindex与msgcontent文件中。如果是接收到的,也存到msgindex2中。 # load_msghead() * 对应 MsgBox.LoadMsgHead() 读出某个消息头,可以指定全消息箱还是收件箱。 # get_msgcount() * 对应 MsgBox.GetMsgCount() 获取消息数量。 # clear_msg() * 对应 MsgBox.ClearMsg() 清除所有消息 # get_unreadcount() * 对应 MsgBox.GetUnreadCount() 获取未读消息数 # get_unreadmsg() * 对应 MsgBox.GetUnreadMsg() 从收件箱里获取某条消息,并且修改已读指针。 # load_msgtext() * 对应 MsgBox.LoadMsgText() 读取某条消息的内容。 # sendmsgfunc() 发送消息。 # translate_msg() 转换?目前具体不明 # mail_msg() 将所有消息放入邮件寄回信箱。 # mailbacklastmsg() 将未发送成功消息寄回信箱。 === SMS支持 === 不在研究范围…… === SQL相关 === 意义不明…… 貌似是通讯录一类的东西 ee88b79d0b2ea516890b9f84e804c966c06520a7 129 128 2012-01-30T02:50:59Z HenryHu 1 /* libmsg.c */ wikitext text/x-wiki == 数据结构 == === 消息索引 === # msgindex:全消息箱 # msgindex2:收件箱 * 0x00-0x03 4字节 ** 对于收件箱:已读消息个数 * 之后:struct msghead[] == libmsg.c == ; save_msgtext() * 对应 MsgBox.SaveMsgText() : 把消息存到用户的msgindex与msgcontent文件中。如果是接收到的,也存到msgindex2中。 ; load_msghead() * 对应 MsgBox.LoadMsgHead() : 读出某个消息头,可以指定全消息箱还是收件箱。 ; get_msgcount() * 对应 MsgBox.GetMsgCount() : 获取消息数量。 ; clear_msg() * 对应 MsgBox.ClearMsg() : 清除所有消息 ; get_unreadcount() * 对应 MsgBox.GetUnreadCount() : 获取未读消息数 ; get_unreadmsg() * 对应 MsgBox.GetUnreadMsg() : 从收件箱里获取某条消息,并且修改已读指针。 ; load_msgtext() * 对应 MsgBox.LoadMsgText() : 读取某条消息的内容。 ; sendmsgfunc() : 发送消息。 ; translate_msg() : 转换?目前具体不明 ; mail_msg() : 将所有消息放入邮件寄回信箱。 ; mailbacklastmsg() : 将未发送成功消息寄回信箱。 === SMS支持 === 不在研究范围…… === SQL相关 === 意义不明…… 貌似是通讯录一类的东西 a370301ee29aff0f62ee937b119ed77ff81d10a1 130 129 2012-01-30T02:53:21Z HenryHu 1 /* 消息索引 */ wikitext text/x-wiki == 数据结构 == === 消息索引 === # msgindex:全消息箱 # msgindex2:收件箱 * 0x00-0x03 4字节 ** 对于收件箱:已读消息个数 * 之后:struct msghead[] ** 对应 MsgHead <source lang="c"> struct msghead { int pos, len; // 消息体在msgcontent中的位置&长度 char sent; // 1: 发送的消息 0: 收到的消息 char mode; // char id[IDLEN+2]; // 发送/接收者ID time_t time; // 发送/接收时间 int frompid, topid; // 发送/接收者进程号 }; </source> == libmsg.c == ; save_msgtext() * 对应 MsgBox.SaveMsgText() : 把消息存到用户的msgindex与msgcontent文件中。如果是接收到的,也存到msgindex2中。 ; load_msghead() * 对应 MsgBox.LoadMsgHead() : 读出某个消息头,可以指定全消息箱还是收件箱。 ; get_msgcount() * 对应 MsgBox.GetMsgCount() : 获取消息数量。 ; clear_msg() * 对应 MsgBox.ClearMsg() : 清除所有消息 ; get_unreadcount() * 对应 MsgBox.GetUnreadCount() : 获取未读消息数 ; get_unreadmsg() * 对应 MsgBox.GetUnreadMsg() : 从收件箱里获取某条消息,并且修改已读指针。 ; load_msgtext() * 对应 MsgBox.LoadMsgText() : 读取某条消息的内容。 ; sendmsgfunc() : 发送消息。 ; translate_msg() : 转换?目前具体不明 ; mail_msg() : 将所有消息放入邮件寄回信箱。 ; mailbacklastmsg() : 将未发送成功消息寄回信箱。 === SMS支持 === 不在研究范围…… === SQL相关 === 意义不明…… 貌似是通讯录一类的东西 34d76887268d40897a47795ad79302d167f47f50 154 130 2012-02-02T23:36:55Z HenryHu 1 wikitext text/x-wiki [[Category:BBS 代码分析]] == 数据结构 == === 消息索引 === # msgindex:全消息箱 # msgindex2:收件箱 * 0x00-0x03 4字节 ** 对于收件箱:已读消息个数 * 之后:struct msghead[] ** 对应 MsgHead <source lang="c"> struct msghead { int pos, len; // 消息体在msgcontent中的位置&长度 char sent; // 1: 发送的消息 0: 收到的消息 char mode; // char id[IDLEN+2]; // 发送/接收者ID time_t time; // 发送/接收时间 int frompid, topid; // 发送/接收者进程号 }; </source> == libmsg.c == ; save_msgtext() * 对应 MsgBox.SaveMsgText() : 把消息存到用户的msgindex与msgcontent文件中。如果是接收到的,也存到msgindex2中。 ; load_msghead() * 对应 MsgBox.LoadMsgHead() : 读出某个消息头,可以指定全消息箱还是收件箱。 ; get_msgcount() * 对应 MsgBox.GetMsgCount() : 获取消息数量。 ; clear_msg() * 对应 MsgBox.ClearMsg() : 清除所有消息 ; get_unreadcount() * 对应 MsgBox.GetUnreadCount() : 获取未读消息数 ; get_unreadmsg() * 对应 MsgBox.GetUnreadMsg() : 从收件箱里获取某条消息,并且修改已读指针。 ; load_msgtext() * 对应 MsgBox.LoadMsgText() : 读取某条消息的内容。 ; sendmsgfunc() : 发送消息。 ; translate_msg() : 转换?目前具体不明 ; mail_msg() : 将所有消息放入邮件寄回信箱。 ; mailbacklastmsg() : 将未发送成功消息寄回信箱。 === SMS支持 === 不在研究范围…… === SQL相关 === 意义不明…… 貌似是通讯录一类的东西 dc6ad81a7635604b3f0ad1bc199ceaf5cd96ca09 BBS 会话信息 0 50 131 2012-01-30T07:15:40Z HenryHu 1 以内容“BBS的用户相关的东西。这块非常复杂,分成好几个部分。 == UTMP == === UTMPHEAD === <source lang="c"> struct UTMPHEAD { int next[USHM_SIZE]; ...”创建新页面 wikitext text/x-wiki BBS的用户相关的东西。这块非常复杂,分成好几个部分。 == UTMP == === UTMPHEAD === <source lang="c"> struct UTMPHEAD { int next[USHM_SIZE]; int hashhead[UTMP_HASHSIZE + 1]; /* use UCACHE_HASHSIZE/32 */ int number; int listhead; int list_prev[USHM_SIZE]; /* sorted list prev ptr */ int list_next[USHM_SIZE]; /* sorted list next ptr */ time_t uptime; }; static struct UTMPHEAD *utmphead; </source> utmphead其实指向一块shared memory,key = UTMP_SHMKEY == utmp.c == ; get_utmpshm_addr() * Utmp.utmpshm ; longlock [(int signo)] * inside Utmp.Lock() ; utmp_lock * Utmp.Lock() ; utmp_unlock [(int fd)] * Utmp.Unlock() ; utmp_setreadonly [(int readonly)] * UtmpHead.SetReadOnly() ; detach_utmp 仅在WWW中使用。 ; resolve_utmp * Utmp.Init() ; utmp_hash [(const char *userid)] * Utmp.Hash() logloop ; getnewutmpent [(struct user_info *up)] * Utmp.GetNewUtmpEntry() ; getnewutmpent2 [(struct user_info *up)] 仅在WWW中使用。 rebuild_list [(struct user_info *up, char *arg, int p)] apply_ulist [(APPLY_UTMP_FUNC fptr, void *arg)] apply_ulist_addr [(APPLY_UTMP_FUNC fptr, void *arg)] apply_utmpuid [(APPLY_UTMP_FUNC fptr, int uid, void *arg)] apply_utmp [(APPLY_UTMP_FUNC fptr, int maxcount,const char *userid, void *arg)] search_ulist [(struct user_info *uentp, int (*fptr) (int, struct user_info *), int farg)] ; clear_utmp2 [(int uent)] * Utmp.Clear() clear_utmp [(int uent, int useridx, int pid)] ; get_utmp_number * UtmpHead.GetNumber() get_utmpent [(int utmpnum)] get_utmpent_num [(struct user_info *uent)] cmpfuid [(const void*a,const void*b)] getfriendstr [(struct userec* user,struct user_info* puinfo)] myfriend [(int uid, char *fexp)] hisfriend [(int uid,struct user_info* him)] 8d1cac0f01c4842d8336ea20fc1e93288814ebc5 132 131 2012-01-30T07:57:48Z HenryHu 1 /* UTMPHEAD */ wikitext text/x-wiki BBS的用户相关的东西。这块非常复杂,分成好几个部分。 == UTMP == === UTMPHEAD === <source lang="c"> struct UTMPHEAD { int next[USHM_SIZE]; int hashhead[UTMP_HASHSIZE + 1]; /* use UCACHE_HASHSIZE/32 */ int number; int listhead; int list_prev[USHM_SIZE]; /* sorted list prev ptr */ int list_next[USHM_SIZE]; /* sorted list next ptr */ time_t uptime; }; static struct UTMPHEAD *utmphead; </source> utmphead其实指向一块shared memory,key = UTMP_SHMKEY UTMPHEAD结构/数据由UtmpHead类处理,全都为GetXXX/SetXXX形式。 == utmp.c == ; get_utmpshm_addr() * Utmp.utmpshm ; longlock [(int signo)] * inside Utmp.Lock() ; utmp_lock * Utmp.Lock() ; utmp_unlock [(int fd)] * Utmp.Unlock() ; utmp_setreadonly [(int readonly)] * UtmpHead.SetReadOnly() ; detach_utmp 仅在WWW中使用。 ; resolve_utmp * Utmp.Init() ; utmp_hash [(const char *userid)] * Utmp.Hash() logloop ; getnewutmpent [(struct user_info *up)] * Utmp.GetNewUtmpEntry() ; getnewutmpent2 [(struct user_info *up)] 仅在WWW中使用。 rebuild_list [(struct user_info *up, char *arg, int p)] apply_ulist [(APPLY_UTMP_FUNC fptr, void *arg)] apply_ulist_addr [(APPLY_UTMP_FUNC fptr, void *arg)] apply_utmpuid [(APPLY_UTMP_FUNC fptr, int uid, void *arg)] apply_utmp [(APPLY_UTMP_FUNC fptr, int maxcount,const char *userid, void *arg)] search_ulist [(struct user_info *uentp, int (*fptr) (int, struct user_info *), int farg)] ; clear_utmp2 [(int uent)] * Utmp.Clear() clear_utmp [(int uent, int useridx, int pid)] ; get_utmp_number * UtmpHead.GetNumber() get_utmpent [(int utmpnum)] get_utmpent_num [(struct user_info *uent)] cmpfuid [(const void*a,const void*b)] getfriendstr [(struct userec* user,struct user_info* puinfo)] myfriend [(int uid, char *fexp)] hisfriend [(int uid,struct user_info* him)] 1a1422eb734a55f91c650aba36376d44f87c3fcf 133 132 2012-01-30T08:54:58Z HenryHu 1 /* utmp.c */ wikitext text/x-wiki BBS的用户相关的东西。这块非常复杂,分成好几个部分。 == UTMP == === UTMPHEAD === <source lang="c"> struct UTMPHEAD { int next[USHM_SIZE]; int hashhead[UTMP_HASHSIZE + 1]; /* use UCACHE_HASHSIZE/32 */ int number; int listhead; int list_prev[USHM_SIZE]; /* sorted list prev ptr */ int list_next[USHM_SIZE]; /* sorted list next ptr */ time_t uptime; }; static struct UTMPHEAD *utmphead; </source> utmphead其实指向一块shared memory,key = UTMP_SHMKEY UTMPHEAD结构/数据由UtmpHead类处理,全都为GetXXX/SetXXX形式。 == utmp.c == ; get_utmpshm_addr() * Utmp.utmpshm ; longlock [(int signo)] * inside Utmp.Lock() ; utmp_lock * Utmp.Lock() ; utmp_unlock [(int fd)] * Utmp.Unlock() ; utmp_setreadonly [(int readonly)] * UtmpHead.SetReadOnly() ; detach_utmp 仅在WWW中使用。 ; resolve_utmp * Utmp.Init() ; utmp_hash [(const char *userid)] * Utmp.Hash() logloop ; getnewutmpent [(struct user_info *up)] * Utmp.GetNewUtmpEntry() ; getnewutmpent2 [(struct user_info *up)] 仅在WWW中使用。 rebuild_list [(struct user_info *up, char *arg, int p)] apply_ulist [(APPLY_UTMP_FUNC fptr, void *arg)] apply_ulist_addr [(APPLY_UTMP_FUNC fptr, void *arg)] apply_utmpuid [(APPLY_UTMP_FUNC fptr, int uid, void *arg)] apply_utmp [(APPLY_UTMP_FUNC fptr, int maxcount,const char *userid, void *arg)] search_ulist [(struct user_info *uentp, int (*fptr) (int, struct user_info *), int farg)] ; clear_utmp2 [(int uent)] * Utmp.Clear() clear_utmp [(int uent, int useridx, int pid)] ; get_utmp_number * UtmpHead.GetNumber() get_utmpent [(int utmpnum)] get_utmpent_num [(struct user_info *uent)] cmpfuid [(const void*a,const void*b)] getfriendstr [(struct userec* user,struct user_info* puinfo)] myfriend [(int uid, char *fexp)] hisfriend [(int uid,struct user_info* him)] == ucache.c == ; ucache_lock ; ucache_unlock [(int fd)] ucache_hashinit ucache_hash_deep [(const char *userid)] ucache_hash [(const char *userid)] fillucache [(struct userec *uentp, int *number, int *prev)] flush_ucache load_ucache ; resolve_ucache * UCache.Init() detach_ucache getuserid [(char *userid, int uid)] setuserid_internal [(int num, const char *userid)] setuserid2 [(int num, const char *userid)] setuserid [(int num, const char *userid)] searchnewuser ; searchuser [(const char *userid)] * UCache.SearchUser() ; getuser [(const char *userid, struct userec **user)] * UCache.GetUser() getuserid2 [(int uid)] u_namearray [(char buf[][IDLEN + 1], int *pnum, char *tag)] getnewuserid3 [(char *userid)] getnewuserid2 [(char *userid)] ; getuserbynum [(int num)] * UCache.GetUserByUid() getnewuserid [(char *userid)] update_user [(struct userec *user, int num, int all)] apply_users [(int (*fptr) (struct userec *, char *), char *arg)] get_giveupinfo [(char* userid,int* basicperm,int s[10][2])] save_giveupinfo [(struct userec* lookupuser,int lcount,int s[10][2])] setcachehomefile [(char* path,const char* user,int unum,char* file)] init_cachedata [(const char* userid,int unum)] flush_cachedata [(const char* userid)] clean_cachedata [(const char* userid,int unum)] do_after_login [(struct userec* user,int unum,int mode)] do_after_logout [(struct userec* user,struct user_info* userinfo,int unum,int mode)] === 自定义User Title相关 === load_user_title flush_user_title get_user_title [(unsigned char titleidx)] set_user_title [(unsigned char titleidx,char* newtitle)] === WWW相关 === longlock [(int signo)] www_guest_lock www_guest_unlock [(int fd)] resolve_guest_table eb0c0d7f8baf838660c120b47bd01e6ffdddf59b 134 133 2012-01-30T09:05:22Z HenryHu 1 /* UTMPHEAD */ wikitext text/x-wiki BBS的用户相关的东西。这块非常复杂,分成好几个部分。 == UTMP == === UTMPHEAD === <source lang="c"> struct UTMPHEAD { int next[USHM_SIZE]; int hashhead[UTMP_HASHSIZE + 1]; /* use UCACHE_HASHSIZE/32 */ int number; int listhead; int list_prev[USHM_SIZE]; /* sorted list prev ptr */ int list_next[USHM_SIZE]; /* sorted list next ptr */ time_t uptime; }; static struct UTMPHEAD *utmphead; </source> utmphead其实指向一块shared memory,key = UTMPHEAD_SHMKEY UTMPHEAD结构/数据由UtmpHead类处理,全都为GetXXX/SetXXX形式。 listhead, list_prev和list_next构成一个单向循环链表,listhead是表头,里面按照不分大小写的userid排列。 hashhead和next构成一个拉链式散列表,hashhead是表头,next是链上下一个。 number是登录用户数。uptime是上次刷新用户列表的时间。 === UTMPFILE === * 摘自KBS网站 utmpshm 的类型是 UTMPFILE 结构,用来存储登录的状态信息。注意 wwwguest 和这个结构完全没有关系。 这其实也是一块shared memory, key = UTMP_SHMKEY <source lang="C"> #define USHM_SIZE (MAXACTIVE + 10) struct UTMPFILE { struct user_info uinfo[USHM_SIZE]; // 登录状态信息。每个登录都有一个登录号(utmpnum),他就是该登录在 // uinfo 数组中的位置,注意 utmpnum 是 1-based。 }; </source> uinfo 数组的每一个元素都可以用来存储一个登录的状态信息,其结构 user_info 定义: <source lang="C"> struct user_info { /* Structure used in UTMP file */ int active; /* When allocated this field is true */ // 本结构当前是否代表一个登录用户。 int uid; /* Used to find user name in passwd file */ // 登录用户的 uid。 int pid; /* kill() to notify user of talk request */ // telnet 登录表示其进程号。www 登录设置为 1。 int invisible; /* Used by cloaking function in Xyz menu */ // 是否隐身。 int sockactive; /* Used to coordinate talk requests */ int sockaddr; /* ... */ int destuid; /* talk uses this to identify who called */ int mode; /* UL/DL, Talk Mode, Chat Mode, ... */ // 状态,应该赋值为 modes.h 里面的常数。 int pager; /* pager toggle, true, or false */ /* 呼叫器状态,bitwise-OR 以下属性 ALL_PAGER 0x1 FRIEND_PAGER 0x2 ALLMSG_PAGER 0x4 FRIENDMSG_PAGER 0x8 */ int in_chat; /* for in_chat commands */ char chatid[16]; /* chat id, if in chat mode */ char from[IPLEN + 4]; /* machine name the user called in from */ // 登录 IP。 time_t logintime; // 登录时间戳。 int lastpost; // 上次发文的时间戳。 char unused[32]; time_t freshtime; // 上次活动的时间戳,用来计算发呆时间。 int utmpkey; // 登录 key,用于 www cookie 验证保持用户身份。 unsigned int mailbox_prop; /* properties of getCurrentUser()'s mailbox */ // 用户信箱选项,登录时从用户 .mailbox.prop 文件读取,参考 3.3 节 char userid[20]; // 用户名 char realname[20]; // 真实姓名,登录时从用户 userdata 结构读取 char username[40]; // 用户昵称,登录时从 uidshm 共享内存去读取,修改临时昵称就是修改这个字段 int friendsnum; // 好友数量 int friends_uid[MAXFRIENDS]; // 每个好友的 uid,前 friendsnum 个有效。 #ifdef FRIEND_MULTI_GROUP unsigned int friends_p[MAXFRIENDS]; #endif int currentboard; // 当前所在版面的 bid 号 unsigned int mailcheck; /* if have new mail or new msg, stiger */ // 当前登录是否有新信或新消息 }; </source> == utmp.c == ; get_utmpshm_addr() * Utmp.utmpshm ; longlock [(int signo)] * inside Utmp.Lock() ; utmp_lock * Utmp.Lock() ; utmp_unlock [(int fd)] * Utmp.Unlock() ; utmp_setreadonly [(int readonly)] * UtmpHead.SetReadOnly() ; detach_utmp 仅在WWW中使用。 ; resolve_utmp * Utmp.Init() ; utmp_hash [(const char *userid)] * Utmp.Hash() logloop ; getnewutmpent [(struct user_info *up)] * Utmp.GetNewUtmpEntry() ; getnewutmpent2 [(struct user_info *up)] 仅在WWW中使用。 rebuild_list [(struct user_info *up, char *arg, int p)] apply_ulist [(APPLY_UTMP_FUNC fptr, void *arg)] apply_ulist_addr [(APPLY_UTMP_FUNC fptr, void *arg)] apply_utmpuid [(APPLY_UTMP_FUNC fptr, int uid, void *arg)] apply_utmp [(APPLY_UTMP_FUNC fptr, int maxcount,const char *userid, void *arg)] search_ulist [(struct user_info *uentp, int (*fptr) (int, struct user_info *), int farg)] ; clear_utmp2 [(int uent)] * Utmp.Clear() clear_utmp [(int uent, int useridx, int pid)] ; get_utmp_number * UtmpHead.GetNumber() get_utmpent [(int utmpnum)] get_utmpent_num [(struct user_info *uent)] cmpfuid [(const void*a,const void*b)] getfriendstr [(struct userec* user,struct user_info* puinfo)] myfriend [(int uid, char *fexp)] hisfriend [(int uid,struct user_info* him)] == ucache.c == ; ucache_lock ; ucache_unlock [(int fd)] ucache_hashinit ucache_hash_deep [(const char *userid)] ucache_hash [(const char *userid)] fillucache [(struct userec *uentp, int *number, int *prev)] flush_ucache load_ucache ; resolve_ucache * UCache.Init() detach_ucache getuserid [(char *userid, int uid)] setuserid_internal [(int num, const char *userid)] setuserid2 [(int num, const char *userid)] setuserid [(int num, const char *userid)] searchnewuser ; searchuser [(const char *userid)] * UCache.SearchUser() ; getuser [(const char *userid, struct userec **user)] * UCache.GetUser() getuserid2 [(int uid)] u_namearray [(char buf[][IDLEN + 1], int *pnum, char *tag)] getnewuserid3 [(char *userid)] getnewuserid2 [(char *userid)] ; getuserbynum [(int num)] * UCache.GetUserByUid() getnewuserid [(char *userid)] update_user [(struct userec *user, int num, int all)] apply_users [(int (*fptr) (struct userec *, char *), char *arg)] get_giveupinfo [(char* userid,int* basicperm,int s[10][2])] save_giveupinfo [(struct userec* lookupuser,int lcount,int s[10][2])] setcachehomefile [(char* path,const char* user,int unum,char* file)] init_cachedata [(const char* userid,int unum)] flush_cachedata [(const char* userid)] clean_cachedata [(const char* userid,int unum)] do_after_login [(struct userec* user,int unum,int mode)] do_after_logout [(struct userec* user,struct user_info* userinfo,int unum,int mode)] === 自定义User Title相关 === load_user_title flush_user_title get_user_title [(unsigned char titleidx)] set_user_title [(unsigned char titleidx,char* newtitle)] === WWW相关 === longlock [(int signo)] www_guest_lock www_guest_unlock [(int fd)] resolve_guest_table 646a38b535581516737496a997824ea3078b06a7 136 134 2012-01-31T04:49:14Z HenryHu 1 /* utmp.c */ wikitext text/x-wiki BBS的用户相关的东西。这块非常复杂,分成好几个部分。 == UTMP == === UTMPHEAD === <source lang="c"> struct UTMPHEAD { int next[USHM_SIZE]; int hashhead[UTMP_HASHSIZE + 1]; /* use UCACHE_HASHSIZE/32 */ int number; int listhead; int list_prev[USHM_SIZE]; /* sorted list prev ptr */ int list_next[USHM_SIZE]; /* sorted list next ptr */ time_t uptime; }; static struct UTMPHEAD *utmphead; </source> utmphead其实指向一块shared memory,key = UTMPHEAD_SHMKEY UTMPHEAD结构/数据由UtmpHead类处理,全都为GetXXX/SetXXX形式。 listhead, list_prev和list_next构成一个单向循环链表,listhead是表头,里面按照不分大小写的userid排列。 hashhead和next构成一个拉链式散列表,hashhead是表头,next是链上下一个。 number是登录用户数。uptime是上次刷新用户列表的时间。 === UTMPFILE === * 摘自KBS网站 utmpshm 的类型是 UTMPFILE 结构,用来存储登录的状态信息。注意 wwwguest 和这个结构完全没有关系。 这其实也是一块shared memory, key = UTMP_SHMKEY <source lang="C"> #define USHM_SIZE (MAXACTIVE + 10) struct UTMPFILE { struct user_info uinfo[USHM_SIZE]; // 登录状态信息。每个登录都有一个登录号(utmpnum),他就是该登录在 // uinfo 数组中的位置,注意 utmpnum 是 1-based。 }; </source> uinfo 数组的每一个元素都可以用来存储一个登录的状态信息,其结构 user_info 定义: <source lang="C"> struct user_info { /* Structure used in UTMP file */ int active; /* When allocated this field is true */ // 本结构当前是否代表一个登录用户。 int uid; /* Used to find user name in passwd file */ // 登录用户的 uid。 int pid; /* kill() to notify user of talk request */ // telnet 登录表示其进程号。www 登录设置为 1。 int invisible; /* Used by cloaking function in Xyz menu */ // 是否隐身。 int sockactive; /* Used to coordinate talk requests */ int sockaddr; /* ... */ int destuid; /* talk uses this to identify who called */ int mode; /* UL/DL, Talk Mode, Chat Mode, ... */ // 状态,应该赋值为 modes.h 里面的常数。 int pager; /* pager toggle, true, or false */ /* 呼叫器状态,bitwise-OR 以下属性 ALL_PAGER 0x1 FRIEND_PAGER 0x2 ALLMSG_PAGER 0x4 FRIENDMSG_PAGER 0x8 */ int in_chat; /* for in_chat commands */ char chatid[16]; /* chat id, if in chat mode */ char from[IPLEN + 4]; /* machine name the user called in from */ // 登录 IP。 time_t logintime; // 登录时间戳。 int lastpost; // 上次发文的时间戳。 char unused[32]; time_t freshtime; // 上次活动的时间戳,用来计算发呆时间。 int utmpkey; // 登录 key,用于 www cookie 验证保持用户身份。 unsigned int mailbox_prop; /* properties of getCurrentUser()'s mailbox */ // 用户信箱选项,登录时从用户 .mailbox.prop 文件读取,参考 3.3 节 char userid[20]; // 用户名 char realname[20]; // 真实姓名,登录时从用户 userdata 结构读取 char username[40]; // 用户昵称,登录时从 uidshm 共享内存去读取,修改临时昵称就是修改这个字段 int friendsnum; // 好友数量 int friends_uid[MAXFRIENDS]; // 每个好友的 uid,前 friendsnum 个有效。 #ifdef FRIEND_MULTI_GROUP unsigned int friends_p[MAXFRIENDS]; #endif int currentboard; // 当前所在版面的 bid 号 unsigned int mailcheck; /* if have new mail or new msg, stiger */ // 当前登录是否有新信或新消息 }; </source> == utmp.c == ; get_utmpshm_addr() * Utmp.utmpshm ; longlock [(int signo)] * inside Utmp.Lock() ; utmp_lock * Utmp.Lock() ; utmp_unlock [(int fd)] * Utmp.Unlock() ; utmp_setreadonly [(int readonly)] * UtmpHead.SetReadOnly() ; detach_utmp 仅在WWW中使用。 ; resolve_utmp * Utmp.Init() ; utmp_hash [(const char *userid)] * Utmp.Hash() logloop ; getnewutmpent [(struct user_info *up)] * Utmp.GetNewUtmpEntry() ; getnewutmpent2 [(struct user_info *up)] 仅在WWW中使用。 rebuild_list [(struct user_info *up, char *arg, int p)] apply_ulist [(APPLY_UTMP_FUNC fptr, void *arg)] apply_ulist_addr [(APPLY_UTMP_FUNC fptr, void *arg)] apply_utmpuid [(APPLY_UTMP_FUNC fptr, int uid, void *arg)] apply_utmp [(APPLY_UTMP_FUNC fptr, int maxcount,const char *userid, void *arg)] search_ulist [(struct user_info *uentp, int (*fptr) (int, struct user_info *), int farg)] ; clear_utmp2 [(int uent)] * Utmp.Clear2() '''TODO''' ; clear_utmp [(int uent, int useridx, int pid)] * Utmp.Clear() ; get_utmp_number * UtmpHead.GetNumber() ; get_utmpent [(int utmpnum)] * UserInfo.__init__() ; get_utmpent_num [(struct user_info *uent)] * UserInfo.GetIndex() === 好友相关 === 见[[BBS 好友列表]] cmpfuid [(const void*a,const void*b)] getfriendstr [(struct userec* user,struct user_info* puinfo)] myfriend [(int uid, char *fexp)] hisfriend [(int uid,struct user_info* him)] == ucache.c == ; ucache_lock ; ucache_unlock [(int fd)] ucache_hashinit ucache_hash_deep [(const char *userid)] ucache_hash [(const char *userid)] fillucache [(struct userec *uentp, int *number, int *prev)] flush_ucache load_ucache ; resolve_ucache * UCache.Init() detach_ucache getuserid [(char *userid, int uid)] setuserid_internal [(int num, const char *userid)] setuserid2 [(int num, const char *userid)] setuserid [(int num, const char *userid)] searchnewuser ; searchuser [(const char *userid)] * UCache.SearchUser() ; getuser [(const char *userid, struct userec **user)] * UCache.GetUser() getuserid2 [(int uid)] u_namearray [(char buf[][IDLEN + 1], int *pnum, char *tag)] getnewuserid3 [(char *userid)] getnewuserid2 [(char *userid)] ; getuserbynum [(int num)] * UCache.GetUserByUid() getnewuserid [(char *userid)] update_user [(struct userec *user, int num, int all)] apply_users [(int (*fptr) (struct userec *, char *), char *arg)] get_giveupinfo [(char* userid,int* basicperm,int s[10][2])] save_giveupinfo [(struct userec* lookupuser,int lcount,int s[10][2])] setcachehomefile [(char* path,const char* user,int unum,char* file)] init_cachedata [(const char* userid,int unum)] flush_cachedata [(const char* userid)] clean_cachedata [(const char* userid,int unum)] do_after_login [(struct userec* user,int unum,int mode)] do_after_logout [(struct userec* user,struct user_info* userinfo,int unum,int mode)] === 自定义User Title相关 === load_user_title flush_user_title get_user_title [(unsigned char titleidx)] set_user_title [(unsigned char titleidx,char* newtitle)] === WWW相关 === longlock [(int signo)] www_guest_lock www_guest_unlock [(int fd)] resolve_guest_table b555cb7f53548371627daa02655ace3d0606443d 143 136 2012-02-01T04:03:30Z HenryHu 1 [[BBS 用户信息]]移动到[[BBS 会话信息]] wikitext text/x-wiki BBS的用户相关的东西。这块非常复杂,分成好几个部分。 == UTMP == === UTMPHEAD === <source lang="c"> struct UTMPHEAD { int next[USHM_SIZE]; int hashhead[UTMP_HASHSIZE + 1]; /* use UCACHE_HASHSIZE/32 */ int number; int listhead; int list_prev[USHM_SIZE]; /* sorted list prev ptr */ int list_next[USHM_SIZE]; /* sorted list next ptr */ time_t uptime; }; static struct UTMPHEAD *utmphead; </source> utmphead其实指向一块shared memory,key = UTMPHEAD_SHMKEY UTMPHEAD结构/数据由UtmpHead类处理,全都为GetXXX/SetXXX形式。 listhead, list_prev和list_next构成一个单向循环链表,listhead是表头,里面按照不分大小写的userid排列。 hashhead和next构成一个拉链式散列表,hashhead是表头,next是链上下一个。 number是登录用户数。uptime是上次刷新用户列表的时间。 === UTMPFILE === * 摘自KBS网站 utmpshm 的类型是 UTMPFILE 结构,用来存储登录的状态信息。注意 wwwguest 和这个结构完全没有关系。 这其实也是一块shared memory, key = UTMP_SHMKEY <source lang="C"> #define USHM_SIZE (MAXACTIVE + 10) struct UTMPFILE { struct user_info uinfo[USHM_SIZE]; // 登录状态信息。每个登录都有一个登录号(utmpnum),他就是该登录在 // uinfo 数组中的位置,注意 utmpnum 是 1-based。 }; </source> uinfo 数组的每一个元素都可以用来存储一个登录的状态信息,其结构 user_info 定义: <source lang="C"> struct user_info { /* Structure used in UTMP file */ int active; /* When allocated this field is true */ // 本结构当前是否代表一个登录用户。 int uid; /* Used to find user name in passwd file */ // 登录用户的 uid。 int pid; /* kill() to notify user of talk request */ // telnet 登录表示其进程号。www 登录设置为 1。 int invisible; /* Used by cloaking function in Xyz menu */ // 是否隐身。 int sockactive; /* Used to coordinate talk requests */ int sockaddr; /* ... */ int destuid; /* talk uses this to identify who called */ int mode; /* UL/DL, Talk Mode, Chat Mode, ... */ // 状态,应该赋值为 modes.h 里面的常数。 int pager; /* pager toggle, true, or false */ /* 呼叫器状态,bitwise-OR 以下属性 ALL_PAGER 0x1 FRIEND_PAGER 0x2 ALLMSG_PAGER 0x4 FRIENDMSG_PAGER 0x8 */ int in_chat; /* for in_chat commands */ char chatid[16]; /* chat id, if in chat mode */ char from[IPLEN + 4]; /* machine name the user called in from */ // 登录 IP。 time_t logintime; // 登录时间戳。 int lastpost; // 上次发文的时间戳。 char unused[32]; time_t freshtime; // 上次活动的时间戳,用来计算发呆时间。 int utmpkey; // 登录 key,用于 www cookie 验证保持用户身份。 unsigned int mailbox_prop; /* properties of getCurrentUser()'s mailbox */ // 用户信箱选项,登录时从用户 .mailbox.prop 文件读取,参考 3.3 节 char userid[20]; // 用户名 char realname[20]; // 真实姓名,登录时从用户 userdata 结构读取 char username[40]; // 用户昵称,登录时从 uidshm 共享内存去读取,修改临时昵称就是修改这个字段 int friendsnum; // 好友数量 int friends_uid[MAXFRIENDS]; // 每个好友的 uid,前 friendsnum 个有效。 #ifdef FRIEND_MULTI_GROUP unsigned int friends_p[MAXFRIENDS]; #endif int currentboard; // 当前所在版面的 bid 号 unsigned int mailcheck; /* if have new mail or new msg, stiger */ // 当前登录是否有新信或新消息 }; </source> == utmp.c == ; get_utmpshm_addr() * Utmp.utmpshm ; longlock [(int signo)] * inside Utmp.Lock() ; utmp_lock * Utmp.Lock() ; utmp_unlock [(int fd)] * Utmp.Unlock() ; utmp_setreadonly [(int readonly)] * UtmpHead.SetReadOnly() ; detach_utmp 仅在WWW中使用。 ; resolve_utmp * Utmp.Init() ; utmp_hash [(const char *userid)] * Utmp.Hash() logloop ; getnewutmpent [(struct user_info *up)] * Utmp.GetNewUtmpEntry() ; getnewutmpent2 [(struct user_info *up)] 仅在WWW中使用。 rebuild_list [(struct user_info *up, char *arg, int p)] apply_ulist [(APPLY_UTMP_FUNC fptr, void *arg)] apply_ulist_addr [(APPLY_UTMP_FUNC fptr, void *arg)] apply_utmpuid [(APPLY_UTMP_FUNC fptr, int uid, void *arg)] apply_utmp [(APPLY_UTMP_FUNC fptr, int maxcount,const char *userid, void *arg)] search_ulist [(struct user_info *uentp, int (*fptr) (int, struct user_info *), int farg)] ; clear_utmp2 [(int uent)] * Utmp.Clear2() '''TODO''' ; clear_utmp [(int uent, int useridx, int pid)] * Utmp.Clear() ; get_utmp_number * UtmpHead.GetNumber() ; get_utmpent [(int utmpnum)] * UserInfo.__init__() ; get_utmpent_num [(struct user_info *uent)] * UserInfo.GetIndex() === 好友相关 === 见[[BBS 好友列表]] cmpfuid [(const void*a,const void*b)] getfriendstr [(struct userec* user,struct user_info* puinfo)] myfriend [(int uid, char *fexp)] hisfriend [(int uid,struct user_info* him)] == ucache.c == ; ucache_lock ; ucache_unlock [(int fd)] ucache_hashinit ucache_hash_deep [(const char *userid)] ucache_hash [(const char *userid)] fillucache [(struct userec *uentp, int *number, int *prev)] flush_ucache load_ucache ; resolve_ucache * UCache.Init() detach_ucache getuserid [(char *userid, int uid)] setuserid_internal [(int num, const char *userid)] setuserid2 [(int num, const char *userid)] setuserid [(int num, const char *userid)] searchnewuser ; searchuser [(const char *userid)] * UCache.SearchUser() ; getuser [(const char *userid, struct userec **user)] * UCache.GetUser() getuserid2 [(int uid)] u_namearray [(char buf[][IDLEN + 1], int *pnum, char *tag)] getnewuserid3 [(char *userid)] getnewuserid2 [(char *userid)] ; getuserbynum [(int num)] * UCache.GetUserByUid() getnewuserid [(char *userid)] update_user [(struct userec *user, int num, int all)] apply_users [(int (*fptr) (struct userec *, char *), char *arg)] get_giveupinfo [(char* userid,int* basicperm,int s[10][2])] save_giveupinfo [(struct userec* lookupuser,int lcount,int s[10][2])] setcachehomefile [(char* path,const char* user,int unum,char* file)] init_cachedata [(const char* userid,int unum)] flush_cachedata [(const char* userid)] clean_cachedata [(const char* userid,int unum)] do_after_login [(struct userec* user,int unum,int mode)] do_after_logout [(struct userec* user,struct user_info* userinfo,int unum,int mode)] === 自定义User Title相关 === load_user_title flush_user_title get_user_title [(unsigned char titleidx)] set_user_title [(unsigned char titleidx,char* newtitle)] === WWW相关 === longlock [(int signo)] www_guest_lock www_guest_unlock [(int fd)] resolve_guest_table b555cb7f53548371627daa02655ace3d0606443d 145 143 2012-02-01T04:04:41Z HenryHu 1 /* ucache.c */ wikitext text/x-wiki BBS的用户相关的东西。这块非常复杂,分成好几个部分。 == UTMP == === UTMPHEAD === <source lang="c"> struct UTMPHEAD { int next[USHM_SIZE]; int hashhead[UTMP_HASHSIZE + 1]; /* use UCACHE_HASHSIZE/32 */ int number; int listhead; int list_prev[USHM_SIZE]; /* sorted list prev ptr */ int list_next[USHM_SIZE]; /* sorted list next ptr */ time_t uptime; }; static struct UTMPHEAD *utmphead; </source> utmphead其实指向一块shared memory,key = UTMPHEAD_SHMKEY UTMPHEAD结构/数据由UtmpHead类处理,全都为GetXXX/SetXXX形式。 listhead, list_prev和list_next构成一个单向循环链表,listhead是表头,里面按照不分大小写的userid排列。 hashhead和next构成一个拉链式散列表,hashhead是表头,next是链上下一个。 number是登录用户数。uptime是上次刷新用户列表的时间。 === UTMPFILE === * 摘自KBS网站 utmpshm 的类型是 UTMPFILE 结构,用来存储登录的状态信息。注意 wwwguest 和这个结构完全没有关系。 这其实也是一块shared memory, key = UTMP_SHMKEY <source lang="C"> #define USHM_SIZE (MAXACTIVE + 10) struct UTMPFILE { struct user_info uinfo[USHM_SIZE]; // 登录状态信息。每个登录都有一个登录号(utmpnum),他就是该登录在 // uinfo 数组中的位置,注意 utmpnum 是 1-based。 }; </source> uinfo 数组的每一个元素都可以用来存储一个登录的状态信息,其结构 user_info 定义: <source lang="C"> struct user_info { /* Structure used in UTMP file */ int active; /* When allocated this field is true */ // 本结构当前是否代表一个登录用户。 int uid; /* Used to find user name in passwd file */ // 登录用户的 uid。 int pid; /* kill() to notify user of talk request */ // telnet 登录表示其进程号。www 登录设置为 1。 int invisible; /* Used by cloaking function in Xyz menu */ // 是否隐身。 int sockactive; /* Used to coordinate talk requests */ int sockaddr; /* ... */ int destuid; /* talk uses this to identify who called */ int mode; /* UL/DL, Talk Mode, Chat Mode, ... */ // 状态,应该赋值为 modes.h 里面的常数。 int pager; /* pager toggle, true, or false */ /* 呼叫器状态,bitwise-OR 以下属性 ALL_PAGER 0x1 FRIEND_PAGER 0x2 ALLMSG_PAGER 0x4 FRIENDMSG_PAGER 0x8 */ int in_chat; /* for in_chat commands */ char chatid[16]; /* chat id, if in chat mode */ char from[IPLEN + 4]; /* machine name the user called in from */ // 登录 IP。 time_t logintime; // 登录时间戳。 int lastpost; // 上次发文的时间戳。 char unused[32]; time_t freshtime; // 上次活动的时间戳,用来计算发呆时间。 int utmpkey; // 登录 key,用于 www cookie 验证保持用户身份。 unsigned int mailbox_prop; /* properties of getCurrentUser()'s mailbox */ // 用户信箱选项,登录时从用户 .mailbox.prop 文件读取,参考 3.3 节 char userid[20]; // 用户名 char realname[20]; // 真实姓名,登录时从用户 userdata 结构读取 char username[40]; // 用户昵称,登录时从 uidshm 共享内存去读取,修改临时昵称就是修改这个字段 int friendsnum; // 好友数量 int friends_uid[MAXFRIENDS]; // 每个好友的 uid,前 friendsnum 个有效。 #ifdef FRIEND_MULTI_GROUP unsigned int friends_p[MAXFRIENDS]; #endif int currentboard; // 当前所在版面的 bid 号 unsigned int mailcheck; /* if have new mail or new msg, stiger */ // 当前登录是否有新信或新消息 }; </source> == utmp.c == ; get_utmpshm_addr() * Utmp.utmpshm ; longlock [(int signo)] * inside Utmp.Lock() ; utmp_lock * Utmp.Lock() ; utmp_unlock [(int fd)] * Utmp.Unlock() ; utmp_setreadonly [(int readonly)] * UtmpHead.SetReadOnly() ; detach_utmp 仅在WWW中使用。 ; resolve_utmp * Utmp.Init() ; utmp_hash [(const char *userid)] * Utmp.Hash() logloop ; getnewutmpent [(struct user_info *up)] * Utmp.GetNewUtmpEntry() ; getnewutmpent2 [(struct user_info *up)] 仅在WWW中使用。 rebuild_list [(struct user_info *up, char *arg, int p)] apply_ulist [(APPLY_UTMP_FUNC fptr, void *arg)] apply_ulist_addr [(APPLY_UTMP_FUNC fptr, void *arg)] apply_utmpuid [(APPLY_UTMP_FUNC fptr, int uid, void *arg)] apply_utmp [(APPLY_UTMP_FUNC fptr, int maxcount,const char *userid, void *arg)] search_ulist [(struct user_info *uentp, int (*fptr) (int, struct user_info *), int farg)] ; clear_utmp2 [(int uent)] * Utmp.Clear2() '''TODO''' ; clear_utmp [(int uent, int useridx, int pid)] * Utmp.Clear() ; get_utmp_number * UtmpHead.GetNumber() ; get_utmpent [(int utmpnum)] * UserInfo.__init__() ; get_utmpent_num [(struct user_info *uent)] * UserInfo.GetIndex() === 好友相关 === 见[[BBS 好友列表]] cmpfuid [(const void*a,const void*b)] getfriendstr [(struct userec* user,struct user_info* puinfo)] myfriend [(int uid, char *fexp)] hisfriend [(int uid,struct user_info* him)] da48ce8645ce7f973a05db373ca45bcec21e78ad BBS 好友列表 0 51 135 2012-01-31T00:45:39Z HenryHu 1 以内容“== friends == <source lang="c"> struct friends { char id[13]; char exp[LEN_FRIEND_EXP]; #ifdef FRIEND_MULTI_GROUP int groupid; #endif }; struct friends_inf...”创建新页面 wikitext text/x-wiki == friends == <source lang="c"> struct friends { char id[13]; char exp[LEN_FRIEND_EXP]; #ifdef FRIEND_MULTI_GROUP int groupid; #endif }; struct friends_info { char exp[LEN_FRIEND_EXP]; }; struct friends_group { char name[15]; unsigned int p; char f; char b; }; </source> 410b0f32763d85c80f27a0b3232e4508f83682b6 137 135 2012-01-31T05:17:35Z HenryHu 1 /* friends */ wikitext text/x-wiki == friends == <source lang="c"> struct friends { char id[13]; char exp[LEN_FRIEND_EXP]; #ifdef FRIEND_MULTI_GROUP int groupid; #endif }; struct friends_info { char exp[LEN_FRIEND_EXP]; }; struct friends_group { char name[15]; unsigned int p; char f; char b; }; </source> == utmp.c == ; cmpfuid [(const void*a,const void*b)] * Friend.NCaseId() ; getfriendstr [(struct userec* user,struct user_info* puinfo)] * User.GetFriends() ; myfriend [(int uid, char *fexp)] * UserInfo.HasFriend() ; hisfriend [(int uid,struct user_info* him)] * UserInfo.HasFriend() 861840fbc2c742b3885a2ecc4bec938a753b0b43 139 137 2012-01-31T06:51:03Z HenryHu 1 wikitext text/x-wiki = UI部分 = 入口函数:src/list.c deal_key() = 逻辑部分 = == friends == <source lang="c"> // 部分 struct user_info { /* Structure used in UTMP file */ int active; /* When allocated this field is true */ int uid; /* Used to find user name in passwd file */ int pid; /* kill() to notify user of talk request */ // ... int friendsnum; int friends_uid[MAXFRIENDS]; #ifdef FRIEND_MULTI_GROUP unsigned int friends_p[MAXFRIENDS]; #endif // ... }; // friends文件就是这个东西的一个数组 struct friends { char id[13]; // 用户名 char exp[LEN_FRIEND_EXP]; // 昵称,默认为空 #ifdef FRIEND_MULTI_GROUP int groupid; #endif }; struct friends_info { char exp[LEN_FRIEND_EXP]; // 存储昵称用 }; struct friends_info* topfriend; // 存储了好友的昵称 // 次序按照用户名经过处理排序后的,对照userinfo.friends_uid </source> == utmp.c == ; cmpfuid [(const void*a,const void*b)] * Friend.NCaseId() ; getfriendstr [(struct userec* user,struct user_info* puinfo)] * User.GetFriends() ; myfriend [(int uid, char *fexp)] * UserInfo.HasFriend() ; hisfriend [(int uid,struct user_info* him)] * UserInfo.HasFriend() d8b3e3877177ecad01a9d577ab7dd72591dfa45e 140 139 2012-01-31T07:03:14Z HenryHu 1 /* friends */ wikitext text/x-wiki = UI部分 = 入口函数:src/list.c deal_key() = 逻辑部分 = == friends == <source lang="c"> // 部分 struct user_info { /* Structure used in UTMP file */ int active; /* When allocated this field is true */ int uid; /* Used to find user name in passwd file */ int pid; /* kill() to notify user of talk request */ // ... int friendsnum; int friends_uid[MAXFRIENDS]; #ifdef FRIEND_MULTI_GROUP unsigned int friends_p[MAXFRIENDS]; #endif // ... }; struct user_info *user_record[USHM_SIZE]; // friends文件就是这个东西的一个数组 struct friends { char id[13]; // 用户名 char exp[LEN_FRIEND_EXP]; // 昵称,默认为空 #ifdef FRIEND_MULTI_GROUP int groupid; #endif }; struct friends_info { char exp[LEN_FRIEND_EXP]; // 存储昵称用 }; struct friends_info* topfriend; // 存储了好友的昵称 // 次序按照用户名经过处理排序后的,对照userinfo.friends_uid </source> == utmp.c == ; cmpfuid [(const void*a,const void*b)] * Friend.NCaseId() ; getfriendstr [(struct userec* user,struct user_info* puinfo)] * User.GetFriends() ; myfriend [(int uid, char *fexp)] * UserInfo.HasFriend() ; hisfriend [(int uid,struct user_info* him)] * UserInfo.HasFriend() c2037ee43b39c8e819d0de11f3eab34554ed8e7f 141 140 2012-01-31T07:19:53Z HenryHu 1 /* utmp.c */ wikitext text/x-wiki = UI部分 = 入口函数:src/list.c deal_key() = 逻辑部分 = == friends == <source lang="c"> // 部分 struct user_info { /* Structure used in UTMP file */ int active; /* When allocated this field is true */ int uid; /* Used to find user name in passwd file */ int pid; /* kill() to notify user of talk request */ // ... int friendsnum; int friends_uid[MAXFRIENDS]; #ifdef FRIEND_MULTI_GROUP unsigned int friends_p[MAXFRIENDS]; #endif // ... }; struct user_info *user_record[USHM_SIZE]; // friends文件就是这个东西的一个数组 struct friends { char id[13]; // 用户名 char exp[LEN_FRIEND_EXP]; // 昵称,默认为空 #ifdef FRIEND_MULTI_GROUP int groupid; #endif }; struct friends_info { char exp[LEN_FRIEND_EXP]; // 存储昵称用 }; struct friends_info* topfriend; // 存储了好友的昵称 // 次序按照用户名经过处理排序后的,对照userinfo.friends_uid </source> == utmp.c == ; cmpfuid [(const void*a,const void*b)] * Friend.NCaseId() ; getfriendstr [(struct userec* user,struct user_info* puinfo)] * User.GetFriends() ; myfriend [(int uid, char *fexp)] * UserInfo.HasFriend() ; hisfriend [(int uid,struct user_info* him)] * UserInfo.HasFriend() == list.c == === TERM显示相关 === ; print_title ; print_title2 ; print_user_info_title ; show_message [(char *msg)] ; pagerchar [(int usernum, struct user_info *user, int pager, int *isfriend)] ; msgchar [(struct user_info *uin, int *isfriend)] ; do_userlist 显示user list。 ; show_userlist 显示user list。调用do_userlist。如果需要刷新则调用fill_userlist()。 ; deal_key ; deal_key2 按键处理。 ; printuent [(struct userec *uentp, char *arg)] 显示用户信息。 ; Show_Users 调用printuent显示所有用户信息。 do_query [(int star, int curr)] do_query2 [(int star, int curr)] ; Users 初始化user_data,调Show_Users显示用户,deal_key2接收按键,do_query2执行。 ; t_friends 调用show_userlist显示好友,deal_key接收按键,do_query执行。 ; t_users 调用show_userlist显示用户,deal_key接收按键,do_query执行。 ; t_rusers 调用t_users显示用户,显示真实用户名。 ; choose [(int update, int defaultn, int (*title_show) (), int (*key_deal) (), int (*list_show) (), int (*read) (),int(*read2)())] 显示、选择、执行函数。 ; setlistrange [(int i)] 设定显示范围。 ; readuser [(int star, int curr)] 调用display_userinfo显示/修改用户信息。 === user_record相关 === update_data [(void *data)] ; swap_user_record 交换user_record两项。 ; sort_user_record 排序user_record ; full_utmp [(struct user_info *uentp, int *count)] 填充user_record一项。 ; fill_userlist 调用full_utmp(),填充user_record ; countusers [(struct userec *uentp, char *arg)] ; allusers 调用countusers()数用户数量。 b28d433a823e50905944fe2ac48830c21020bd30 BBS 用户信息 0 54 146 2012-02-01T04:04:52Z HenryHu 1 以内容“== ucache.c == ; ucache_lock ; ucache_unlock [(int fd)] ucache_hashinit ucache_hash_deep [(const char *userid)] ucache_hash [(const char *userid)] fi...”创建新页面 wikitext text/x-wiki == ucache.c == ; ucache_lock ; ucache_unlock [(int fd)] ucache_hashinit ucache_hash_deep [(const char *userid)] ucache_hash [(const char *userid)] fillucache [(struct userec *uentp, int *number, int *prev)] flush_ucache load_ucache ; resolve_ucache * UCache.Init() detach_ucache getuserid [(char *userid, int uid)] setuserid_internal [(int num, const char *userid)] setuserid2 [(int num, const char *userid)] setuserid [(int num, const char *userid)] searchnewuser ; searchuser [(const char *userid)] * UCache.SearchUser() ; getuser [(const char *userid, struct userec **user)] * UCache.GetUser() getuserid2 [(int uid)] u_namearray [(char buf[][IDLEN + 1], int *pnum, char *tag)] getnewuserid3 [(char *userid)] getnewuserid2 [(char *userid)] ; getuserbynum [(int num)] * UCache.GetUserByUid() getnewuserid [(char *userid)] update_user [(struct userec *user, int num, int all)] apply_users [(int (*fptr) (struct userec *, char *), char *arg)] get_giveupinfo [(char* userid,int* basicperm,int s[10][2])] save_giveupinfo [(struct userec* lookupuser,int lcount,int s[10][2])] setcachehomefile [(char* path,const char* user,int unum,char* file)] init_cachedata [(const char* userid,int unum)] flush_cachedata [(const char* userid)] clean_cachedata [(const char* userid,int unum)] do_after_login [(struct userec* user,int unum,int mode)] do_after_logout [(struct userec* user,struct user_info* userinfo,int unum,int mode)] === 自定义User Title相关 === load_user_title flush_user_title get_user_title [(unsigned char titleidx)] set_user_title [(unsigned char titleidx,char* newtitle)] === WWW相关 === longlock [(int signo)] www_guest_lock www_guest_unlock [(int fd)] resolve_guest_table 0693a1184337951645e6e563d55518f79b1ec066 147 146 2012-02-01T04:08:49Z HenryHu 1 wikitext text/x-wiki == User Record == 一个用户的信息,所有登录共用的。 <source lang="c"> struct userec { /* Structure used to hold information in */ char userid[IDLEN + 2]; /* PASSFILE */ char flags; /*一些标志,戒网,版面排序之类的*/ unsigned char title; /*用户级别*/ time_t firstlogin; char lasthost[16]; unsigned int numlogins; unsigned int numposts; #ifdef CONV_PASS char passwd[OLDPASSLEN]; char unused_padding[2]; #endif char username[NAMELEN]; unsigned int club_read_rights[MAXCLUB>>5]; unsigned int club_write_rights[MAXCLUB>>5]; unsigned char md5passwd[MD5PASSLEN]; unsigned userlevel; time_t lastlogin; time_t stay; int signature; unsigned int userdefine[2]; time_t notedate; int noteline; int notemode; time_t exittime; /* 生日数据转移到 userdata 结构中 */ unsigned int usedspace; /* used space of user's mailbox, in bytes */ #ifdef HAVE_USERMONEY int money; int score; char unused[20]; #endif }; struct UCACHE { ucache_hashtable hashtable; ucache_hashtable hashusage; int hashhead[UCACHE_HASHSIZE + 1]; int next[MAXUSERS]; time_t uptime; int number; #ifdef HAVE_CUSTOM_USER_TITLE char user_title[255][USER_TITLE_LEN]; //定义用户的称号字符串。 #endif struct userec passwd[MAXUSERS]; }; static struct UCACHE *uidshm = NULL; </source> == ucache.c == ; ucache_lock ; ucache_unlock [(int fd)] ucache_hashinit ucache_hash_deep [(const char *userid)] ucache_hash [(const char *userid)] fillucache [(struct userec *uentp, int *number, int *prev)] flush_ucache load_ucache ; resolve_ucache * UCache.Init() detach_ucache getuserid [(char *userid, int uid)] setuserid_internal [(int num, const char *userid)] setuserid2 [(int num, const char *userid)] setuserid [(int num, const char *userid)] searchnewuser ; searchuser [(const char *userid)] * UCache.SearchUser() ; getuser [(const char *userid, struct userec **user)] * UCache.GetUser() getuserid2 [(int uid)] u_namearray [(char buf[][IDLEN + 1], int *pnum, char *tag)] getnewuserid3 [(char *userid)] getnewuserid2 [(char *userid)] ; getuserbynum [(int num)] * UCache.GetUserByUid() getnewuserid [(char *userid)] update_user [(struct userec *user, int num, int all)] apply_users [(int (*fptr) (struct userec *, char *), char *arg)] get_giveupinfo [(char* userid,int* basicperm,int s[10][2])] save_giveupinfo [(struct userec* lookupuser,int lcount,int s[10][2])] setcachehomefile [(char* path,const char* user,int unum,char* file)] init_cachedata [(const char* userid,int unum)] flush_cachedata [(const char* userid)] clean_cachedata [(const char* userid,int unum)] do_after_login [(struct userec* user,int unum,int mode)] do_after_logout [(struct userec* user,struct user_info* userinfo,int unum,int mode)] === 自定义User Title相关 === load_user_title flush_user_title get_user_title [(unsigned char titleidx)] set_user_title [(unsigned char titleidx,char* newtitle)] === WWW相关 === longlock [(int signo)] www_guest_lock www_guest_unlock [(int fd)] resolve_guest_table 57a965e651ee993457770fb8b0586f4f6c9f5453 Pybbs 0 56 149 2012-02-01T09:12:22Z HenryHu 1 以内容“基于Python的BBS实现,提供[[BBS数据接口]]。 == XMPP实现 == XMPP阶段: * 认证 ** 基于外部OAuth * 登录 ** 更新用户信息 ** 增加session * ...”创建新页面 wikitext text/x-wiki 基于Python的BBS实现,提供[[BBS数据接口]]。 == XMPP实现 == XMPP阶段: * 认证 ** 基于外部OAuth * 登录 ** 更新用户信息 ** 增加session * 获取好友列表(roaster) * 发送消息 * 消息通知 * 接收消息 * 增加好友 * 删除好友 * 修改好友昵称 * 修改状态 ed1e1435dbc437fb7645c5e4e1a322416f9e1c40 152 149 2012-02-02T07:24:17Z HenryHu 1 /* XMPP实现 */ wikitext text/x-wiki 基于Python的BBS实现,提供[[BBS数据接口]]。 == XMPP实现 == XMPP阶段: * 认证 ** 基于外部OAuth ** 基于明文 TLS层已经加密了,所以无所谓。'''已实现''' * 登录 ** 更新用户信息 ** 增加session * 获取好友列表(roaster) * 发送消息 * 消息通知 * 接收消息 * 增加好友 * 删除好友 * 修改好友昵称 * 修改状态 5b3bebc463d7b7ba8dc7ea5b34a32e485c839f09 153 152 2012-02-02T07:28:39Z HenryHu 1 /* XMPP实现 */ wikitext text/x-wiki 基于Python的BBS实现,提供[[BBS数据接口]]。 == XMPP实现 == XMPP阶段: * 认证 ** 基于外部OAuth ** 基于明文 TLS层已经加密了,所以无所谓。'''已实现,见xmppauth.XMPPAuth类''' * 登录 ** 更新用户信息 ** 增加session * 获取好友列表(roaster) * 发送消息 * 消息通知 * 接收消息 * 增加好友 * 删除好友 * 修改好友昵称 * 修改状态 e038b698a02eb14556acfbd9bc5077a7988cedba 模板:Group 10 59 155 2012-02-02T23:39:24Z HenryHu 1 以内容“{{group_{{{1}}}|{{{2}}}|{{{2}}}|size={{{size|}}}|name={{{name|}}}}}”创建新页面 wikitext text/x-wiki {{group_{{{1}}}|{{{2}}}|{{{2}}}|size={{{size|}}}|name={{{name|}}}}} 93da8f347fafa801168785fc9ba3d3fa56d97614 模板:Template group 10 60 156 2012-02-02T23:40:27Z HenryHu 1 以内容“{{group_{{{1}}}|{{{2}}}|{{{2}}}|size={{{size|}}}|name={{{name|}}}}}”创建新页面 wikitext text/x-wiki {{group_{{{1}}}|{{{2}}}|{{{2}}}|size={{{size|}}}|name={{{name|}}}}} 93da8f347fafa801168785fc9ba3d3fa56d97614 157 156 2012-02-02T23:41:27Z HenryHu 1 wikitext text/x-wiki {{Navbox |navbar = plain |title = {{{title|Links to related articles}}} |list1 = {{{list1|{{{list|}}}}}} |state = {{{state|collapsed}}} |titlestyle = {{{titlestyle|}}} |liststyle = padding:0px; font-size:113%; |listpadding = 0px; }}<noinclude> {{documentation}} </noinclude> 497db08a6b4fbaf22791232b9d7ff78cb2378592 模板:Navbox 10 61 158 2012-02-02T23:41:56Z HenryHu 1 以内容“<!-- Please do not edit without discussion first as this is a VERY complex template. -->{{#switch:{{{border|{{{1|}}}}}}|subgroup|child=</div>|none=|#default=<table ce...”创建新页面 wikitext text/x-wiki <!-- Please do not edit without discussion first as this is a VERY complex template. -->{{#switch:{{{border|{{{1|}}}}}}|subgroup|child=</div>|none=|#default=<table cellspacing="0" <!-- -->class="navbox" style="border-spacing:0;{{{bodystyle|}}};{{{style|}}}"><tr><td style="padding:2px;">}}<!-- --><table cellspacing="0" class="nowraplinks {{{bodyclass|}}} {{#if:{{{title|}}}|{{#switch:{{{state|}}}|<!-- -->plain|off=|#default=collapsible {{#if:{{{state|}}}|{{{state}}}|autocollapse}}}}}} {{#switch:{{{border|{{{1|}}}}}}|<!-- -->subgroup|child|none=navbox-subgroup" style="border-spacing:0;{{{bodystyle|}}};{{{style|}}}|<!-- -->#default=navbox-inner" style="border-spacing:0;background:transparent;color:inherit}};{{{innerstyle|}}};"><!-- ---Title and Navbar--- -->{{#if:{{{title|}}}|<tr>{{#if:{{{titlegroup|}}}|<!-- --><th scope="row" class="navbox-group {{{titlegroupclass|}}}" <!-- -->style="{{{basestyle|}}};{{{groupstyle|}}};{{{titlegroupstyle|}}}"><!-- -->{{{titlegroup|}}}</th><th scope="col" style="border-left:2px solid #fdfdfd;width:100%;|<!-- --><th scope="col" style="}}{{{basestyle|}}};{{{titlestyle|}}}" class="navbox-title" <!-- -->colspan={{#expr:2{{#if:{{{imageleft|}}}|+1}}{{#if:{{{image|}}}|+1}}{{#if:{{{titlegroup|}}}|-1}}}}><!-- -->{{#if:{{#switch:{{{navbar|}}}|plain|off=1}}<!-- -->{{#if:{{{name|}}}||{{#switch:{{{border|{{{1|}}}}}}|subgroup|child|none=1}}}}|<!-- -->{{#ifeq:{{{navbar|}}}|off|{{#ifeq:{{{state|}}}|plain|<span style="float:right;width:6em;">&nbsp;</span>}}|<!-- -->{{#ifeq:{{{state|}}}|plain||<span style="float:left;width:6em;">&nbsp;</span>}}}}|<!-- -->{{#if:{{{name|}}}|{{Navbar|{{{name}}}|mini=1|<!-- -->fontstyle={{{basestyle|}}};{{{titlestyle|}}};background:none transparent;border:none;}}|<!-- --><span class="error" style="float:left;white-space:nowrap;">Error: No name provided</span>}}<!-- -->{{#ifeq:{{{state|}}}|plain|<span style="float:right;width:6em;">&nbsp;</span>}}}}<!-- --><div class="{{{titleclass|}}}" style="font-size:110%;"> {{{title}}}</div></th></tr>}}<!-- ---Above--- -->{{#if:{{{above|}}}|<!-- -->{{#if:{{{title|}}}|<tr style="height:2px;"><td></td></tr>}}<!-- --><tr><td class="navbox-abovebelow {{{aboveclass|}}}" style="{{{basestyle|}}};{{{abovestyle|}}}" <!-- -->colspan="{{#expr:2{{#if:{{{imageleft|}}}|+1}}{{#if:{{{image|}}}|+1}}}}"><div> {{{above}}}</div></td></tr>}}<!-- ---Body--- ---First group/list and images--- -->{{#if:{{{list1|}}}|{{#if:{{{title|}}}{{{above|}}}|<tr style="height:2px;"><td></td></tr>}}<tr><!-- -->{{#if:{{{imageleft|}}}|<!-- --><td class="navbox-image {{{imageclass|}}}" style="width:0%;padding:0px 2px 0px 0px;{{{imageleftstyle|}}}" <!-- -->rowspan={{#expr:1{{#if:{{{list2|}}}|+2}}{{#if:{{{list3|}}}|+2}}{{#if:{{{list4|}}}|+2}}<!-- -->{{#if:{{{list5|}}}|+2}}{{#if:{{{list6|}}}|+2}}{{#if:{{{list7|}}}|+2}}{{#if:{{{list8|}}}|+2}}<!-- -->{{#if:{{{list9|}}}|+2}}{{#if:{{{list10|}}}|+2}}{{#if:{{{list11|}}}|+2}}{{#if:{{{list12|}}}|+2}}<!-- -->{{#if:{{{list13|}}}|+2}}{{#if:{{{list14|}}}|+2}}{{#if:{{{list15|}}}|+2}}{{#if:{{{list16|}}}|+2}}<!-- -->{{#if:{{{list17|}}}|+2}}{{#if:{{{list18|}}}|+2}}{{#if:{{{list19|}}}|+2}}{{#if:{{{list20|}}}|+2}}}}><div> {{{imageleft}}}</div></td>}}<!-- -->{{#if:{{{group1|}}}|<th scope="row" class="navbox-group {{{groupclass|}}}" <!-- -->style="{{{basestyle|}}};{{#if:{{{groupwidth|}}}|width:{{{groupwidth}}};}}{{{groupstyle|}}};{{{group1style|}}}"><!-- -->{{{group1}}}</th><td style="text-align:left;border-left-width:2px;border-left-style:solid;|<td colspan=2 style="}}<!-- -->{{#if:{{{groupwidth|}}}||width:100%;}}padding:0px;{{{liststyle|}}};{{{oddstyle|}}};{{{list1style|}}}" <!-- -->class="navbox-list navbox-{{#ifeq:{{{evenodd|}}}|swap|even|{{{evenodd|odd}}}}} {{{listclass|}}}"><!-- --><div style="padding:{{{list1padding|{{{listpadding|0em 0.25em}}}}}}"> {{{list1}}}</div></td><!-- -->{{#if:{{{image|}}}|<!-- --><td class="navbox-image {{{imageclass|}}}" style="width:0%;padding:0px 0px 0px 2px;{{{imagestyle|}}}" <!-- -->rowspan={{#expr:1{{#if:{{{list2|}}}|+2}}{{#if:{{{list3|}}}|+2}}{{#if:{{{list4|}}}|+2}}<!-- -->{{#if:{{{list5|}}}|+2}}{{#if:{{{list6|}}}|+2}}{{#if:{{{list7|}}}|+2}}{{#if:{{{list8|}}}|+2}}<!-- -->{{#if:{{{list9|}}}|+2}}{{#if:{{{list10|}}}|+2}}{{#if:{{{list11|}}}|+2}}{{#if:{{{list12|}}}|+2}}<!-- -->{{#if:{{{list13|}}}|+2}}{{#if:{{{list14|}}}|+2}}{{#if:{{{list15|}}}|+2}}{{#if:{{{list16|}}}|+2}}<!-- -->{{#if:{{{list17|}}}|+2}}{{#if:{{{list18|}}}|+2}}{{#if:{{{list19|}}}|+2}}{{#if:{{{list20|}}}|+2}}}}><div> {{{image}}}</div></td>}}<!-- --></tr>}}<!-- ---Remaining groups/lists--- -->{{#if:{{{list2|}}}|<!-- -->{{#if:{{{title|}}}{{{above|}}}{{{list1|}}}|<tr style="height:2px"><td></td></tr>}}<tr><!-- -->{{#if:{{{group2|}}}|<th scope="row" class="navbox-group {{{groupclass|}}}" <!-- -->style="{{{basestyle|}}};{{#if:{{{groupwidth|}}}|width:{{{groupwidth}}};}}{{{groupstyle|}}};{{{group2style|}}}"><!-- -->{{{group2}}}</th><td style="text-align:left;border-left-width:2px;border-left-style:solid;|<td colspan=2 style="}}<!-- -->{{#if:{{{groupwidth|}}}||width:100%;}}padding:0px;{{{liststyle|}}};{{{evenstyle|}}};{{{list2style|}}}" <!-- -->class="navbox-list navbox-{{#ifeq:{{{evenodd|}}}|swap|odd|{{{evenodd|even}}}}} {{{listclass|}}}"><!-- --><div style="padding:{{{listpadding|0em 0.25em}}}"> {{{list2}}}</div></td></tr>}}<!-- -->{{#if:{{{list3|}}}|<!-- -->{{#if:{{{title|}}}{{{above|}}}{{{list1|}}}{{{list2|}}}|<tr style="height:2px"><td></td></tr>}}<tr><!-- -->{{#if:{{{group3|}}}|<th scope="row" class="navbox-group {{{groupclass|}}}" <!-- -->style="{{{basestyle|}}};{{#if:{{{groupwidth|}}}|width:{{{groupwidth}}};}}{{{groupstyle|}}};{{{group3style|}}}"><!-- -->{{{group3}}}</th><td style="text-align:left;border-left-width:2px;border-left-style:solid;|<td colspan=2 style="}}<!-- -->{{#if:{{{groupwidth|}}}||width:100%;}}padding:0px;{{{liststyle|}}};{{{oddstyle|}}};{{{list3style|}}}" <!-- -->class="navbox-list navbox-{{#ifeq:{{{evenodd|}}}|swap|even|{{{evenodd|odd}}}}} {{{listclass|}}}"><!-- --><div style="padding:{{{listpadding|0em 0.25em}}}"> {{{list3}}}</div></td></tr>}}<!-- -->{{#if:{{{list4|}}}|<!-- --><tr style="height:2px"><td></td></tr><tr><!-- -->{{#if:{{{group4|}}}|<th scope="row" class="navbox-group {{{groupclass|}}}" <!-- -->style="{{{basestyle|}}};{{#if:{{{groupwidth|}}}|width:{{{groupwidth}}};}}{{{groupstyle|}}};{{{group4style|}}}"><!-- -->{{{group4}}}</th><td style="text-align:left;border-left-width:2px;border-left-style:solid;|<td colspan=2 style="}}<!-- -->{{#if:{{{groupwidth|}}}||width:100%;}}padding:0px;{{{liststyle|}}};{{{evenstyle|}}};{{{list4style|}}}" <!-- -->class="navbox-list navbox-{{#ifeq:{{{evenodd|}}}|swap|odd|{{{evenodd|even}}}}} {{{listclass|}}}"><!-- --><div style="padding:{{{listpadding|0em 0.25em}}}"> {{{list4}}}</div></td></tr>}}<!-- -->{{#if:{{{list5|}}}|<!-- --><tr style="height:2px"><td></td></tr><tr><!-- -->{{#if:{{{group5|}}}|<th scope="row" class="navbox-group {{{groupclass|}}}" <!-- -->style="{{{basestyle|}}};{{#if:{{{groupwidth|}}}|width:{{{groupwidth}}};}}{{{groupstyle|}}};{{{group5style|}}}"><!-- -->{{{group5}}}</th><td style="text-align:left;border-left-width:2px;border-left-style:solid;|<td colspan=2 style="}}<!-- -->{{#if:{{{groupwidth|}}}||width:100%;}}padding:0px;{{{liststyle|}}};{{{oddstyle|}}};{{{list5style|}}}" <!-- -->class="navbox-list navbox-{{#ifeq:{{{evenodd|}}}|swap|even|{{{evenodd|odd}}}}} {{{listclass|}}}"><!-- --><div style="padding:{{{listpadding|0em 0.25em}}}"> {{{list5}}}</div></td></tr>}}<!-- -->{{#if:{{{list6|}}}|<!-- --><tr style="height:2px"><td></td></tr><tr><!-- -->{{#if:{{{group6|}}}|<th scope="row" class="navbox-group {{{groupclass|}}}" <!-- -->style="{{{basestyle|}}};{{#if:{{{groupwidth|}}}|width:{{{groupwidth}}};}}{{{groupstyle|}}};{{{group6style|}}}"><!-- -->{{{group6}}}</th><td style="text-align:left;border-left-width:2px;border-left-style:solid;|<td colspan=2 style="}}<!-- -->{{#if:{{{groupwidth|}}}||width:100%;}}padding:0px;{{{liststyle|}}};{{{evenstyle|}}};{{{list6style|}}}" <!-- -->class="navbox-list navbox-{{#ifeq:{{{evenodd|}}}|swap|odd|{{{evenodd|even}}}}} {{{listclass|}}}"><!-- --><div style="padding:{{{listpadding|0em 0.25em}}}"> {{{list6}}}</div></td></tr>}}<!-- -->{{#if:{{{list7|}}}|<!-- --><tr style="height:2px"><td></td></tr><tr><!-- -->{{#if:{{{group7|}}}|<th scope="row" class="navbox-group {{{groupclass|}}}" <!-- -->style="{{{basestyle|}}};{{#if:{{{groupwidth|}}}|width:{{{groupwidth}}};}}{{{groupstyle|}}};{{{group7style|}}}"><!-- -->{{{group7}}}</th><td style="text-align:left;border-left-width:2px;border-left-style:solid;|<td colspan=2 style="}}<!-- -->{{#if:{{{groupwidth|}}}||width:100%;}}padding:0px;{{{liststyle|}}};{{{oddstyle|}}};{{{list7style|}}}" <!-- -->class="navbox-list navbox-{{#ifeq:{{{evenodd|}}}|swap|even|{{{evenodd|odd}}}}} {{{listclass|}}}"><!-- --><div style="padding:{{{listpadding|0em 0.25em}}}"> {{{list7}}}</div></td></tr>}}<!-- -->{{#if:{{{list8|}}}|<!-- --><tr style="height:2px"><td></td></tr><tr><!-- -->{{#if:{{{group8|}}}|<th scope="row" class="navbox-group {{{groupclass|}}}" <!-- -->style="{{{basestyle|}}};{{#if:{{{groupwidth|}}}|width:{{{groupwidth}}};}}{{{groupstyle|}}};{{{group8style|}}}"><!-- -->{{{group8}}}</th><td style="text-align:left;border-left-width:2px;border-left-style:solid;|<td colspan=2 style="}}<!-- -->{{#if:{{{groupwidth|}}}||width:100%;}}padding:0px;{{{liststyle|}}};{{{evenstyle|}}};{{{list8style|}}}" <!-- -->class="navbox-list navbox-{{#ifeq:{{{evenodd|}}}|swap|odd|{{{evenodd|even}}}}} {{{listclass|}}}"><!-- --><div style="padding:{{{listpadding|0em 0.25em}}}"> {{{list8}}}</div></td></tr>}}<!-- -->{{#if:{{{list9|}}}|<!-- --><tr style="height:2px"><td></td></tr><tr><!-- -->{{#if:{{{group9|}}}|<th scope="row" class="navbox-group {{{groupclass|}}}" <!-- -->style="{{{basestyle|}}};{{#if:{{{groupwidth|}}}|width:{{{groupwidth}}};}}{{{groupstyle|}}};{{{group9style|}}}"><!-- -->{{{group9}}}</th><td style="text-align:left;border-left-width:2px;border-left-style:solid;|<td colspan=2 style="}}<!-- -->{{#if:{{{groupwidth|}}}||width:100%;}}padding:0px;{{{liststyle|}}};{{{oddstyle|}}};{{{list9style|}}}" <!-- -->class="navbox-list navbox-{{#ifeq:{{{evenodd|}}}|swap|even|{{{evenodd|odd}}}}} {{{listclass|}}}"><!-- --><div style="padding:{{{listpadding|0em 0.25em}}}"> {{{list9}}}</div></td></tr>}}<!-- -->{{#if:{{{list10|}}}|<!-- --><tr style="height:2px"><td></td></tr><tr><!-- -->{{#if:{{{group10|}}}|<th scope="row" class="navbox-group {{{groupclass|}}}" <!-- -->style="{{{basestyle|}}};{{#if:{{{groupwidth|}}}|width:{{{groupwidth}}};}}{{{groupstyle|}}};{{{group10style|}}}"><!-- -->{{{group10}}}</th><td style="text-align:left;border-left-width:2px;border-left-style:solid;|<td colspan=2 style="}}<!-- -->{{#if:{{{groupwidth|}}}||width:100%;}}padding:0px;{{{liststyle|}}};{{{evenstyle|}}};{{{list10style|}}}" <!-- -->class="navbox-list navbox-{{#ifeq:{{{evenodd|}}}|swap|odd|{{{evenodd|even}}}}} {{{listclass|}}}"><!-- --><div style="padding:{{{listpadding|0em 0.25em}}}"> {{{list10}}}</div></td></tr>}}<!-- -->{{#if:{{{list11|}}}|<!-- --><tr style="height:2px"><td></td></tr><tr><!-- -->{{#if:{{{group11|}}}|<th scope="row" class="navbox-group {{{groupclass|}}}" <!-- -->style="{{{basestyle|}}};{{#if:{{{groupwidth|}}}|width:{{{groupwidth}}};}}{{{groupstyle|}}};{{{group11style|}}}"><!-- -->{{{group11}}}</th><td style="text-align:left;border-left-width:2px;border-left-style:solid;|<td colspan=2 style="}}<!-- -->{{#if:{{{groupwidth|}}}||width:100%;}}padding:0px;{{{liststyle|}}};{{{oddstyle|}}};{{{list11style|}}}" <!-- -->class="navbox-list navbox-{{#ifeq:{{{evenodd|}}}|swap|even|{{{evenodd|odd}}}}} {{{listclass|}}}"><!-- --><div style="padding:{{{listpadding|0em 0.25em}}}"> {{{list11}}}</div></td></tr>}}<!-- -->{{#if:{{{list12|}}}|<!-- --><tr style="height:2px"><td></td></tr><tr><!-- -->{{#if:{{{group12|}}}|<th scope="row" class="navbox-group {{{groupclass|}}}" <!-- -->style="{{{basestyle|}}};{{#if:{{{groupwidth|}}}|width:{{{groupwidth}}};}}{{{groupstyle|}}};{{{group12style|}}}"><!-- -->{{{group12}}}</th><td style="text-align:left;border-left-width:2px;border-left-style:solid;|<td colspan=2 style="}}<!-- -->{{#if:{{{groupwidth|}}}||width:100%;}}padding:0px;{{{liststyle|}}};{{{evenstyle|}}};{{{list12style|}}}" <!-- -->class="navbox-list navbox-{{#ifeq:{{{evenodd|}}}|swap|odd|{{{evenodd|even}}}}} {{{listclass|}}}"><!-- --><div style="padding:{{{listpadding|0em 0.25em}}}"> {{{list12}}}</div></td></tr>}}<!-- -->{{#if:{{{list13|}}}|<!-- --><tr style="height:2px"><td></td></tr><tr><!-- -->{{#if:{{{group13|}}}|<th scope="row" class="navbox-group {{{groupclass|}}}" <!-- -->style="{{{basestyle|}}};{{#if:{{{groupwidth|}}}|width:{{{groupwidth}}};}}{{{groupstyle|}}};{{{group13style|}}}"><!-- -->{{{group13}}}</th><td style="text-align:left;border-left-width:2px;border-left-style:solid;|<td colspan=2 style="}}<!-- -->{{#if:{{{groupwidth|}}}||width:100%;}}padding:0px;{{{liststyle|}}};{{{oddstyle|}}};{{{list13style|}}}" <!-- -->class="navbox-list navbox-{{#ifeq:{{{evenodd|}}}|swap|even|{{{evenodd|odd}}}}} {{{listclass|}}}"><!-- --><div style="padding:{{{listpadding|0em 0.25em}}}"> {{{list13}}}</div></td></tr>}}<!-- -->{{#if:{{{list14|}}}|<!-- --><tr style="height:2px"><td></td></tr><tr><!-- -->{{#if:{{{group14|}}}|<th scope="row" class="navbox-group {{{groupclass|}}}" <!-- -->style="{{{basestyle|}}};{{#if:{{{groupwidth|}}}|width:{{{groupwidth}}};}}{{{groupstyle|}}};{{{group14style|}}}"><!-- -->{{{group14}}}</th><td style="text-align:left;border-left-width:2px;border-left-style:solid;|<td colspan=2 style="}}<!-- -->{{#if:{{{groupwidth|}}}||width:100%;}}padding:0px;{{{liststyle|}}};{{{evenstyle|}}};{{{list14style|}}}" <!-- -->class="navbox-list navbox-{{#ifeq:{{{evenodd|}}}|swap|odd|{{{evenodd|even}}}}} {{{listclass|}}}"><!-- --><div style="padding:{{{listpadding|0em 0.25em}}}"> {{{list14}}}</div></td></tr>}}<!-- -->{{#if:{{{list15|}}}|<!-- --><tr style="height:2px"><td></td></tr><tr><!-- -->{{#if:{{{group15|}}}|<th scope="row" class="navbox-group {{{groupclass|}}}" <!-- -->style="{{{basestyle|}}};{{#if:{{{groupwidth|}}}|width:{{{groupwidth}}};}}{{{groupstyle|}}};{{{group15style|}}}"><!-- -->{{{group15}}}</th><td style="text-align:left;border-left-width:2px;border-left-style:solid;|<td colspan=2 style="}}<!-- -->{{#if:{{{groupwidth|}}}||width:100%;}}padding:0px;{{{liststyle|}}};{{{oddstyle|}}};{{{list15style|}}}" <!-- -->class="navbox-list navbox-{{#ifeq:{{{evenodd|}}}|swap|even|{{{evenodd|odd}}}}} {{{listclass|}}}"><!-- --><div style="padding:{{{listpadding|0em 0.25em}}}"> {{{list15}}}</div></td></tr>}}<!-- -->{{#if:{{{list16|}}}|<!-- --><tr style="height:2px"><td></td></tr><tr><!-- -->{{#if:{{{group16|}}}|<th scope="row" class="navbox-group {{{groupclass|}}}" <!-- -->style="{{{basestyle|}}};{{#if:{{{groupwidth|}}}|width:{{{groupwidth}}};}}{{{groupstyle|}}};{{{group16style|}}}"><!-- -->{{{group16}}}</th><td style="text-align:left;border-left-width:2px;border-left-style:solid;|<td colspan=2 style="}}<!-- -->{{#if:{{{groupwidth|}}}||width:100%;}}padding:0px;{{{liststyle|}}};{{{evenstyle|}}};{{{list16style|}}}" <!-- -->class="navbox-list navbox-{{#ifeq:{{{evenodd|}}}|swap|odd|{{{evenodd|even}}}}} {{{listclass|}}}"><!-- --><div style="padding:{{{listpadding|0em 0.25em}}}"> {{{list16}}}</div></td></tr>}}<!-- -->{{#if:{{{list17|}}}|<!-- --><tr style="height:2px"><td></td></tr><tr><!-- -->{{#if:{{{group17|}}}|<th scope="row" class="navbox-group {{{groupclass|}}}" <!-- -->style="{{{basestyle|}}};{{#if:{{{groupwidth|}}}|width:{{{groupwidth}}};}}{{{groupstyle|}}};{{{group17style|}}}"><!-- -->{{{group17}}}</th><td style="text-align:left;border-left-width:2px;border-left-style:solid;|<td colspan=2 style="}}<!-- -->{{#if:{{{groupwidth|}}}||width:100%;}}padding:0px;{{{liststyle|}}};{{{oddstyle|}}};{{{list17style|}}}" <!-- -->class="navbox-list navbox-{{#ifeq:{{{evenodd|}}}|swap|even|{{{evenodd|odd}}}}} {{{listclass|}}}"><!-- --><div style="padding:{{{listpadding|0em 0.25em}}}"> {{{list17}}}</div></td></tr>}}<!-- -->{{#if:{{{list18|}}}|<!-- --><tr style="height:2px"><td></td></tr><tr><!-- -->{{#if:{{{group18|}}}|<th scope="row" class="navbox-group {{{groupclass|}}}" <!-- -->style="{{{basestyle|}}};{{#if:{{{groupwidth|}}}|width:{{{groupwidth}}};}}{{{groupstyle|}}};{{{group18style|}}}"><!-- -->{{{group18}}}</th><td style="text-align:left;border-left-width:2px;border-left-style:solid;|<td colspan=2 style="}}<!-- -->{{#if:{{{groupwidth|}}}||width:100%;}}padding:0px;{{{liststyle|}}};{{{evenstyle|}}};{{{list18style|}}}" <!-- -->class="navbox-list navbox-{{#ifeq:{{{evenodd|}}}|swap|odd|{{{evenodd|even}}}}} {{{listclass|}}}"><!-- --><div style="padding:{{{listpadding|0em 0.25em}}}"> {{{list18}}}</div></td></tr>}}<!-- -->{{#if:{{{list19|}}}|<!-- --><tr style="height:2px"><td></td></tr><tr><!-- -->{{#if:{{{group19|}}}|<th scope="row" class="navbox-group {{{groupclass|}}}" <!-- -->style="{{{basestyle|}}};{{#if:{{{groupwidth|}}}|width:{{{groupwidth}}};}}{{{groupstyle|}}};{{{group19style|}}}"><!-- -->{{{group19}}}</th><td style="text-align:left;border-left-width:2px;border-left-style:solid;|<td colspan=2 style="}}<!-- -->{{#if:{{{groupwidth|}}}||width:100%;}}padding:0px;{{{liststyle|}}};{{{oddstyle|}}};{{{list19style|}}}" <!-- -->class="navbox-list navbox-{{#ifeq:{{{evenodd|}}}|swap|even|{{{evenodd|odd}}}}} {{{listclass|}}}"><!-- --><div style="padding:{{{listpadding|0em 0.25em}}}"> {{{list19}}}</div></td></tr>}}<!-- -->{{#if:{{{list20|}}}|<!-- --><tr style="height:2px"><td></td></tr><tr><!-- -->{{#if:{{{group20|}}}|<th scope="row" class="navbox-group {{{groupclass|}}}" <!-- -->style="{{{basestyle|}}};{{#if:{{{groupwidth|}}}|width:{{{groupwidth}}};}}{{{groupstyle|}}};{{{group20style|}}}"><!-- -->{{{group20}}}</th><td style="text-align:left;border-left-width:2px;border-left-style:solid;|<td colspan=2 style="}}<!-- -->{{#if:{{{groupwidth|}}}||width:100%;}}padding:0px;{{{liststyle|}}};{{{evenstyle|}}};{{{list20style|}}}" <!-- -->class="navbox-list navbox-{{#ifeq:{{{evenodd|}}}|swap|odd|{{{evenodd|even}}}}} {{{listclass|}}}"><!-- --><div style="padding:{{{listpadding|0em 0.25em}}}"> {{{list20}}}</div></td></tr>}}<!-- ---Below--- -->{{#if:{{{below|}}}|<!-- -->{{#if:{{{title|}}}{{{above|}}}{{{list1|}}}{{{list2|}}}{{{list3|}}}|<tr style="height:2px;"><td></td></tr>}}<!-- --><tr><td class="navbox-abovebelow {{{belowclass|}}}" style="{{{basestyle|}}};{{{belowstyle|}}}" <!-- -->colspan="{{#expr:2{{#if:{{{imageleft|}}}|+1}}{{#if:{{{image|}}}|+1}}}}"><div> {{{below}}}</div></td></tr>}}<!-- --></table>{{#switch:{{{border|{{{1|}}}}}}|subgroup|child=<div>|none=|#default=</td></tr></table>}}<!-- --><noinclude> {{documentation}} <!-- Add categories and interwikis to the /doc subpage, not here! --> </noinclude> e3658383875696b0b69ba65ce3e0b093ec35784c 模板:Navbar 10 62 159 2012-02-02T23:42:28Z HenryHu 1 以内容“<includeonly><div class="noprint plainlinks hlist navbar" style="{{{style|}}}"><!-- -->{{#if:{{{mini|}}}{{{plain|}}}|<!--nothing-->|<!--else: --><span style="word-spac...”创建新页面 wikitext text/x-wiki <includeonly><div class="noprint plainlinks hlist navbar" style="{{{style|}}}"><!-- -->{{#if:{{{mini|}}}{{{plain|}}}|<!--nothing-->|<!--else: --><span style="word-spacing:0;{{{fontstyle|}}}">{{{text|This box:}}} </span>}}<!-- -->{{#if:{{{brackets|}}}|<span style="margin-right:-0.125em;{{{fontstyle|}}}">&#91;</span>}}<!-- --><ul><!-- --><li class="nv-view">[[{{transclude|{{{1}}}}}|<span style="{{{fontstyle|}}}" title="View this template"><!-- -->{{#if:{{{mini|}}}|v|view}}</span>]]</li><!-- --><li class="nv-talk">[[{{TALKPAGENAME:{{transclude|{{{1}}}}}}}|<span style="{{{fontstyle|}}}" title="Discuss this template"><!-- -->{{#if:{{{mini|}}}|d|talk}}</span>]]</li><!-- -->{{#if:{{{noedit|}}}|<!--nothing-->|<!--else: --><li class="nv-edit">[{{fullurl:{{transclude|{{{1}}}}}|action=edit}} <span style="{{{fontstyle|}}}" title="Edit this template"><!-- -->{{#if:{{{mini|}}}|e|edit}}</span>]</li>}}<!-- --></ul><!-- -->{{#if:{{{brackets|}}}|<span style="margin-left:-0.125em;{{{fontstyle|}}}">&#93;</span>}}<!-- --></div></includeonly><noinclude> {{documentation}} </noinclude> 9faa9c0e6e32930f3c6ad6552a87e11e2e57a0ce 模板:Documentation 10 63 160 2012-02-02T23:42:48Z HenryHu 1 以内容“<!-- Automatically add {{template sandbox notice}} when on a /sandbox page. -->{{#ifeq: {{SUBPAGENAME}} | sandbox | <div style="clear: both;"></div>{{template sandbox...”创建新页面 wikitext text/x-wiki <!-- Automatically add {{template sandbox notice}} when on a /sandbox page. -->{{#ifeq: {{SUBPAGENAME}} | sandbox | <div style="clear: both;"></div>{{template sandbox notice}} }}<!-- Automatically add {{pp-template}} to protected templates. -->{{template other | {{#ifeq: {{PROTECTIONLEVEL:move}} | sysop | {{pp-template|docusage=yes}} | {{#if: {{PROTECTIONLEVEL:edit}} | {{pp-template|docusage=yes}} | <!--Not protected, or only semi-move-protected--> }} }} }}<!-- Start of green doc box. -->{{documentation/start box2 | preload = {{{preload|}}} <!--Allow custom preloads--> | heading = {{{heading|¬}}} <!--Empty but defined means no header--> | heading-style = {{{heading-style|}}} | content = {{{content|}}} <!--Some namespaces must have the /doc, /sandbox and /testcases in talk space--> | docspace = {{documentation/docspace}} | 1 = {{{1|}}} <!--Other docname, if fed--> <!--The namespace is added in /start box2--> | template page = {{documentation/template page}} }}<!-- Start content --><!-- Start load the /doc content: Note: The line breaks between this comment and the next line are necessary so "=== Headings ===" at the start and end of docs are interpreted. --> {{#switch: {{#if:{{{content|}}}|1|0}}{{#if:{{{1|}}}|1|0}}{{#ifexist:{{{1|}}}|1|0}}{{#ifexist:{{documentation/docspace}}:{{documentation/template page}}/doc|1|0}} | 1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 = {{{content|}}} | 0110 | 0111 = {{ {{{1}}} }} | 0001 | 0011 = {{ {{documentation/docspace}}:{{documentation/template page}}/doc }} | 0000 | 0100 | 0010 | 0101 = }} <!-- End load the /doc content: Note: The line breaks between this comment and the previous line are necessary so "=== Headings ===" at the start and end of docs are interpreted. -->{{documentation/end box2 | preload = {{{preload|}}} <!--Allow custom preloads--> | content = {{{content|}}} | link box = {{{link box|}}} <!--So "link box=off" works--> <!--Some namespaces must have the /doc, /sandbox and /testcases in talk space--> | docspace = {{documentation/docspace}} | 1 = {{{1|}}} <!--Other docname, if fed--> <!--The namespace is added in /end box2--> | template page = {{documentation/template page}} }}<!-- End of green doc box --><noinclude> <!-- Add categories and interwikis to the /doc subpage, not here! --> </noinclude> b212a3ff85891d1e4ad8dd6d50afa0d026cb7e12 BBS 好友列表 0 51 161 141 2012-02-02T23:44:35Z HenryHu 1 /* UI部分 */ wikitext text/x-wiki [[Category:BBS 代码分析]] = UI部分 = 入口函数:src/list.c deal_key() = 逻辑部分 = == friends == <source lang="c"> // 部分 struct user_info { /* Structure used in UTMP file */ int active; /* When allocated this field is true */ int uid; /* Used to find user name in passwd file */ int pid; /* kill() to notify user of talk request */ // ... int friendsnum; int friends_uid[MAXFRIENDS]; #ifdef FRIEND_MULTI_GROUP unsigned int friends_p[MAXFRIENDS]; #endif // ... }; struct user_info *user_record[USHM_SIZE]; // friends文件就是这个东西的一个数组 struct friends { char id[13]; // 用户名 char exp[LEN_FRIEND_EXP]; // 昵称,默认为空 #ifdef FRIEND_MULTI_GROUP int groupid; #endif }; struct friends_info { char exp[LEN_FRIEND_EXP]; // 存储昵称用 }; struct friends_info* topfriend; // 存储了好友的昵称 // 次序按照用户名经过处理排序后的,对照userinfo.friends_uid </source> == utmp.c == ; cmpfuid [(const void*a,const void*b)] * Friend.NCaseId() ; getfriendstr [(struct userec* user,struct user_info* puinfo)] * User.GetFriends() ; myfriend [(int uid, char *fexp)] * UserInfo.HasFriend() ; hisfriend [(int uid,struct user_info* him)] * UserInfo.HasFriend() == list.c == === TERM显示相关 === ; print_title ; print_title2 ; print_user_info_title ; show_message [(char *msg)] ; pagerchar [(int usernum, struct user_info *user, int pager, int *isfriend)] ; msgchar [(struct user_info *uin, int *isfriend)] ; do_userlist 显示user list。 ; show_userlist 显示user list。调用do_userlist。如果需要刷新则调用fill_userlist()。 ; deal_key ; deal_key2 按键处理。 ; printuent [(struct userec *uentp, char *arg)] 显示用户信息。 ; Show_Users 调用printuent显示所有用户信息。 do_query [(int star, int curr)] do_query2 [(int star, int curr)] ; Users 初始化user_data,调Show_Users显示用户,deal_key2接收按键,do_query2执行。 ; t_friends 调用show_userlist显示好友,deal_key接收按键,do_query执行。 ; t_users 调用show_userlist显示用户,deal_key接收按键,do_query执行。 ; t_rusers 调用t_users显示用户,显示真实用户名。 ; choose [(int update, int defaultn, int (*title_show) (), int (*key_deal) (), int (*list_show) (), int (*read) (),int(*read2)())] 显示、选择、执行函数。 ; setlistrange [(int i)] 设定显示范围。 ; readuser [(int star, int curr)] 调用display_userinfo显示/修改用户信息。 === user_record相关 === update_data [(void *data)] ; swap_user_record 交换user_record两项。 ; sort_user_record 排序user_record ; full_utmp [(struct user_info *uentp, int *count)] 填充user_record一项。 ; fill_userlist 调用full_utmp(),填充user_record ; countusers [(struct userec *uentp, char *arg)] ; allusers 调用countusers()数用户数量。 f4808665fa6d7418932909e6389a6f23ecf5de02 165 161 2012-02-03T00:25:37Z HenryHu 1 /* 逻辑部分 */ wikitext text/x-wiki [[Category:BBS 代码分析]] = UI部分 = 入口函数:src/list.c deal_key() = 逻辑部分 = == 载入时间 == 见stack trace <source lang="asm"> #0 getfriendstr (user=0xf79fb884, puinfo=0xf6aa1fd8) at utmp.c:705 #1 0x080cf5f6 in u_enter () at newmain_single.c:184 #2 0x080d1087 in user_login () at newmain_single.c:892 #3 0x080d1916 in main_bbs (convit=0, argv=0xff9f4eea "/home/bbs/bin/sshbbsd") at newmain_single.c:1099 #4 0x0808953a in bbs_main (argv=0xff9f4eea "/home/bbs/bin/sshbbsd") at bbsd_single.c:626 #5 0x08089d82 in bbs_entry () at bbsd_single.c:1008 #6 0x0805c745 in do_exec_no_pty (command=0x0, pw=0x0, display=0x0, auth_proto=0x0, auth_data=0x0) at sshd.c:1792 #7 0x0805c625 in do_authenticated (pw=0x0) at sshd.c:1730 #8 0x0805c453 in do_authentication (user=0x8169ed0, privileged_port=0, cipher_type=3) at sshd.c:1634 #9 0x0805c111 in do_connection (privileged_port=0) at sshd.c:1473 #10 0x0805bd05 in main (ac=1, av=0xff9f2ed4) at sshd.c:1324 </source> == friends == <source lang="c"> // 部分 struct user_info { /* Structure used in UTMP file */ int active; /* When allocated this field is true */ int uid; /* Used to find user name in passwd file */ int pid; /* kill() to notify user of talk request */ // ... int friendsnum; int friends_uid[MAXFRIENDS]; #ifdef FRIEND_MULTI_GROUP unsigned int friends_p[MAXFRIENDS]; #endif // ... }; struct user_info *user_record[USHM_SIZE]; // friends文件就是这个东西的一个数组 struct friends { char id[13]; // 用户名 char exp[LEN_FRIEND_EXP]; // 昵称,默认为空 #ifdef FRIEND_MULTI_GROUP int groupid; #endif }; struct friends_info { char exp[LEN_FRIEND_EXP]; // 存储昵称用 }; struct friends_info* topfriend; // 存储了好友的昵称 // 次序按照用户名经过处理排序后的,对照userinfo.friends_uid </source> == utmp.c == ; cmpfuid [(const void*a,const void*b)] * Friend.NCaseId() ; getfriendstr [(struct userec* user,struct user_info* puinfo)] * User.GetFriends() ; myfriend [(int uid, char *fexp)] * UserInfo.HasFriend() ; hisfriend [(int uid,struct user_info* him)] * UserInfo.HasFriend() == list.c == === TERM显示相关 === ; print_title ; print_title2 ; print_user_info_title ; show_message [(char *msg)] ; pagerchar [(int usernum, struct user_info *user, int pager, int *isfriend)] ; msgchar [(struct user_info *uin, int *isfriend)] ; do_userlist 显示user list。 ; show_userlist 显示user list。调用do_userlist。如果需要刷新则调用fill_userlist()。 ; deal_key ; deal_key2 按键处理。 ; printuent [(struct userec *uentp, char *arg)] 显示用户信息。 ; Show_Users 调用printuent显示所有用户信息。 do_query [(int star, int curr)] do_query2 [(int star, int curr)] ; Users 初始化user_data,调Show_Users显示用户,deal_key2接收按键,do_query2执行。 ; t_friends 调用show_userlist显示好友,deal_key接收按键,do_query执行。 ; t_users 调用show_userlist显示用户,deal_key接收按键,do_query执行。 ; t_rusers 调用t_users显示用户,显示真实用户名。 ; choose [(int update, int defaultn, int (*title_show) (), int (*key_deal) (), int (*list_show) (), int (*read) (),int(*read2)())] 显示、选择、执行函数。 ; setlistrange [(int i)] 设定显示范围。 ; readuser [(int star, int curr)] 调用display_userinfo显示/修改用户信息。 === user_record相关 === update_data [(void *data)] ; swap_user_record 交换user_record两项。 ; sort_user_record 排序user_record ; full_utmp [(struct user_info *uentp, int *count)] 填充user_record一项。 ; fill_userlist 调用full_utmp(),填充user_record ; countusers [(struct userec *uentp, char *arg)] ; allusers 调用countusers()数用户数量。 0fa4198f643da6688a1e6727de786733953bb01f BBS 会话信息 0 50 162 145 2012-02-02T23:44:52Z HenryHu 1 wikitext text/x-wiki [[Category:BBS 代码分析]] BBS的用户相关的东西。这块非常复杂,分成好几个部分。 == UTMP == === UTMPHEAD === <source lang="c"> struct UTMPHEAD { int next[USHM_SIZE]; int hashhead[UTMP_HASHSIZE + 1]; /* use UCACHE_HASHSIZE/32 */ int number; int listhead; int list_prev[USHM_SIZE]; /* sorted list prev ptr */ int list_next[USHM_SIZE]; /* sorted list next ptr */ time_t uptime; }; static struct UTMPHEAD *utmphead; </source> utmphead其实指向一块shared memory,key = UTMPHEAD_SHMKEY UTMPHEAD结构/数据由UtmpHead类处理,全都为GetXXX/SetXXX形式。 listhead, list_prev和list_next构成一个单向循环链表,listhead是表头,里面按照不分大小写的userid排列。 hashhead和next构成一个拉链式散列表,hashhead是表头,next是链上下一个。 number是登录用户数。uptime是上次刷新用户列表的时间。 === UTMPFILE === * 摘自KBS网站 utmpshm 的类型是 UTMPFILE 结构,用来存储登录的状态信息。注意 wwwguest 和这个结构完全没有关系。 这其实也是一块shared memory, key = UTMP_SHMKEY <source lang="C"> #define USHM_SIZE (MAXACTIVE + 10) struct UTMPFILE { struct user_info uinfo[USHM_SIZE]; // 登录状态信息。每个登录都有一个登录号(utmpnum),他就是该登录在 // uinfo 数组中的位置,注意 utmpnum 是 1-based。 }; </source> uinfo 数组的每一个元素都可以用来存储一个登录的状态信息,其结构 user_info 定义: <source lang="C"> struct user_info { /* Structure used in UTMP file */ int active; /* When allocated this field is true */ // 本结构当前是否代表一个登录用户。 int uid; /* Used to find user name in passwd file */ // 登录用户的 uid。 int pid; /* kill() to notify user of talk request */ // telnet 登录表示其进程号。www 登录设置为 1。 int invisible; /* Used by cloaking function in Xyz menu */ // 是否隐身。 int sockactive; /* Used to coordinate talk requests */ int sockaddr; /* ... */ int destuid; /* talk uses this to identify who called */ int mode; /* UL/DL, Talk Mode, Chat Mode, ... */ // 状态,应该赋值为 modes.h 里面的常数。 int pager; /* pager toggle, true, or false */ /* 呼叫器状态,bitwise-OR 以下属性 ALL_PAGER 0x1 FRIEND_PAGER 0x2 ALLMSG_PAGER 0x4 FRIENDMSG_PAGER 0x8 */ int in_chat; /* for in_chat commands */ char chatid[16]; /* chat id, if in chat mode */ char from[IPLEN + 4]; /* machine name the user called in from */ // 登录 IP。 time_t logintime; // 登录时间戳。 int lastpost; // 上次发文的时间戳。 char unused[32]; time_t freshtime; // 上次活动的时间戳,用来计算发呆时间。 int utmpkey; // 登录 key,用于 www cookie 验证保持用户身份。 unsigned int mailbox_prop; /* properties of getCurrentUser()'s mailbox */ // 用户信箱选项,登录时从用户 .mailbox.prop 文件读取,参考 3.3 节 char userid[20]; // 用户名 char realname[20]; // 真实姓名,登录时从用户 userdata 结构读取 char username[40]; // 用户昵称,登录时从 uidshm 共享内存去读取,修改临时昵称就是修改这个字段 int friendsnum; // 好友数量 int friends_uid[MAXFRIENDS]; // 每个好友的 uid,前 friendsnum 个有效。 #ifdef FRIEND_MULTI_GROUP unsigned int friends_p[MAXFRIENDS]; #endif int currentboard; // 当前所在版面的 bid 号 unsigned int mailcheck; /* if have new mail or new msg, stiger */ // 当前登录是否有新信或新消息 }; </source> == utmp.c == ; get_utmpshm_addr() * Utmp.utmpshm ; longlock [(int signo)] * inside Utmp.Lock() ; utmp_lock * Utmp.Lock() ; utmp_unlock [(int fd)] * Utmp.Unlock() ; utmp_setreadonly [(int readonly)] * UtmpHead.SetReadOnly() ; detach_utmp 仅在WWW中使用。 ; resolve_utmp * Utmp.Init() ; utmp_hash [(const char *userid)] * Utmp.Hash() logloop ; getnewutmpent [(struct user_info *up)] * Utmp.GetNewUtmpEntry() ; getnewutmpent2 [(struct user_info *up)] 仅在WWW中使用。 rebuild_list [(struct user_info *up, char *arg, int p)] apply_ulist [(APPLY_UTMP_FUNC fptr, void *arg)] apply_ulist_addr [(APPLY_UTMP_FUNC fptr, void *arg)] apply_utmpuid [(APPLY_UTMP_FUNC fptr, int uid, void *arg)] apply_utmp [(APPLY_UTMP_FUNC fptr, int maxcount,const char *userid, void *arg)] search_ulist [(struct user_info *uentp, int (*fptr) (int, struct user_info *), int farg)] ; clear_utmp2 [(int uent)] * Utmp.Clear2() '''TODO''' ; clear_utmp [(int uent, int useridx, int pid)] * Utmp.Clear() ; get_utmp_number * UtmpHead.GetNumber() ; get_utmpent [(int utmpnum)] * UserInfo.__init__() ; get_utmpent_num [(struct user_info *uent)] * UserInfo.GetIndex() === 好友相关 === 见[[BBS 好友列表]] cmpfuid [(const void*a,const void*b)] getfriendstr [(struct userec* user,struct user_info* puinfo)] myfriend [(int uid, char *fexp)] hisfriend [(int uid,struct user_info* him)] 66013ff93c080949075e453d0f44a0064cd21a22 174 162 2012-02-05T04:13:59Z HenryHu 1 /* utmp.c */ wikitext text/x-wiki [[Category:BBS 代码分析]] BBS的用户相关的东西。这块非常复杂,分成好几个部分。 == UTMP == === UTMPHEAD === <source lang="c"> struct UTMPHEAD { int next[USHM_SIZE]; int hashhead[UTMP_HASHSIZE + 1]; /* use UCACHE_HASHSIZE/32 */ int number; int listhead; int list_prev[USHM_SIZE]; /* sorted list prev ptr */ int list_next[USHM_SIZE]; /* sorted list next ptr */ time_t uptime; }; static struct UTMPHEAD *utmphead; </source> utmphead其实指向一块shared memory,key = UTMPHEAD_SHMKEY UTMPHEAD结构/数据由UtmpHead类处理,全都为GetXXX/SetXXX形式。 listhead, list_prev和list_next构成一个单向循环链表,listhead是表头,里面按照不分大小写的userid排列。 hashhead和next构成一个拉链式散列表,hashhead是表头,next是链上下一个。 number是登录用户数。uptime是上次刷新用户列表的时间。 === UTMPFILE === * 摘自KBS网站 utmpshm 的类型是 UTMPFILE 结构,用来存储登录的状态信息。注意 wwwguest 和这个结构完全没有关系。 这其实也是一块shared memory, key = UTMP_SHMKEY <source lang="C"> #define USHM_SIZE (MAXACTIVE + 10) struct UTMPFILE { struct user_info uinfo[USHM_SIZE]; // 登录状态信息。每个登录都有一个登录号(utmpnum),他就是该登录在 // uinfo 数组中的位置,注意 utmpnum 是 1-based。 }; </source> uinfo 数组的每一个元素都可以用来存储一个登录的状态信息,其结构 user_info 定义: <source lang="C"> struct user_info { /* Structure used in UTMP file */ int active; /* When allocated this field is true */ // 本结构当前是否代表一个登录用户。 int uid; /* Used to find user name in passwd file */ // 登录用户的 uid。 int pid; /* kill() to notify user of talk request */ // telnet 登录表示其进程号。www 登录设置为 1。 int invisible; /* Used by cloaking function in Xyz menu */ // 是否隐身。 int sockactive; /* Used to coordinate talk requests */ int sockaddr; /* ... */ int destuid; /* talk uses this to identify who called */ int mode; /* UL/DL, Talk Mode, Chat Mode, ... */ // 状态,应该赋值为 modes.h 里面的常数。 int pager; /* pager toggle, true, or false */ /* 呼叫器状态,bitwise-OR 以下属性 ALL_PAGER 0x1 FRIEND_PAGER 0x2 ALLMSG_PAGER 0x4 FRIENDMSG_PAGER 0x8 */ int in_chat; /* for in_chat commands */ char chatid[16]; /* chat id, if in chat mode */ char from[IPLEN + 4]; /* machine name the user called in from */ // 登录 IP。 time_t logintime; // 登录时间戳。 int lastpost; // 上次发文的时间戳。 char unused[32]; time_t freshtime; // 上次活动的时间戳,用来计算发呆时间。 int utmpkey; // 登录 key,用于 www cookie 验证保持用户身份。 unsigned int mailbox_prop; /* properties of getCurrentUser()'s mailbox */ // 用户信箱选项,登录时从用户 .mailbox.prop 文件读取,参考 3.3 节 char userid[20]; // 用户名 char realname[20]; // 真实姓名,登录时从用户 userdata 结构读取 char username[40]; // 用户昵称,登录时从 uidshm 共享内存去读取,修改临时昵称就是修改这个字段 int friendsnum; // 好友数量 int friends_uid[MAXFRIENDS]; // 每个好友的 uid,前 friendsnum 个有效。 #ifdef FRIEND_MULTI_GROUP unsigned int friends_p[MAXFRIENDS]; #endif int currentboard; // 当前所在版面的 bid 号 unsigned int mailcheck; /* if have new mail or new msg, stiger */ // 当前登录是否有新信或新消息 }; </source> == utmp.c == ; get_utmpshm_addr() * Utmp.utmpshm ; longlock [(int signo)] * inside Utmp.Lock() ; utmp_lock * Utmp.Lock() ; utmp_unlock [(int fd)] * Utmp.Unlock() ; utmp_setreadonly [(int readonly)] * UtmpHead.SetReadOnly() ; detach_utmp : 仅在WWW中使用。 ; resolve_utmp * Utmp.Init() ; utmp_hash [(const char *userid)] * Utmp.Hash() ; logloop * verify.verifyUtmpHead() : 检测列表是否循环。 ; getnewutmpent [(struct user_info *up)] * Utmp.GetNewUtmpEntry() : 将新建的UserInfo填入空闲的UserInfo中,插入列表和哈希表,增加用户技术等。登录的一部分。 ; getnewutmpent2 [(struct user_info *up)] : 仅在WWW中使用。 ; rebuild_list [(struct user_info *up, char *arg, int p)] * Utmp.RebuildList() '''TODO''' : 重建UtmpHead里的列表。方法是从空的开始一个一个插。 apply_ulist [(APPLY_UTMP_FUNC fptr, void *arg)] apply_ulist_addr [(APPLY_UTMP_FUNC fptr, void *arg)] apply_utmpuid [(APPLY_UTMP_FUNC fptr, int uid, void *arg)] apply_utmp [(APPLY_UTMP_FUNC fptr, int maxcount,const char *userid, void *arg)] search_ulist [(struct user_info *uentp, int (*fptr) (int, struct user_info *), int farg)] ; clear_utmp2 [(int uent)] * Utmp.Clear2() : 清理会话,包括从列表和哈希表删掉,减上站数,清空记录,以及调DoAfterLogout()做收尾工作。 ; clear_utmp [(int uent, int useridx, int pid)] * Utmp.Clear() : 稍作检查,将SHM弄成可写,拿锁,随后调Clear2(),之后防锁,恢复只读。 ; get_utmp_number * UtmpHead.GetNumber() : 拿上站人数 ; get_utmpent [(int utmpnum)] * UserInfo.__init__() ; get_utmpent_num [(struct user_info *uent)] * UserInfo.GetIndex() === 好友相关 === 见[[BBS 好友列表]] cmpfuid [(const void*a,const void*b)] getfriendstr [(struct userec* user,struct user_info* puinfo)] myfriend [(int uid, char *fexp)] hisfriend [(int uid,struct user_info* him)] 3286c43dd10be49dce13716ea1b40f61f57fb85e 175 174 2012-02-05T04:18:28Z HenryHu 1 wikitext text/x-wiki [[Category:BBS 代码分析]] 对应于单个会话,也就是好友列表上一项的内容。一个用户可以有多个会话。 == UTMP == 索引:'''loginid''',有时候也称为utmpent, uent等,就是在UTMPFILE.uinfo里的索引,不过是1为基础的。 === UTMPHEAD === <source lang="c"> struct UTMPHEAD { int next[USHM_SIZE]; int hashhead[UTMP_HASHSIZE + 1]; /* use UCACHE_HASHSIZE/32 */ int number; int listhead; int list_prev[USHM_SIZE]; /* sorted list prev ptr */ int list_next[USHM_SIZE]; /* sorted list next ptr */ time_t uptime; }; static struct UTMPHEAD *utmphead; </source> utmphead其实指向一块shared memory,key = UTMPHEAD_SHMKEY UTMPHEAD结构/数据由UtmpHead类处理,全都为GetXXX/SetXXX形式。 listhead, list_prev和list_next构成一个单向循环链表,listhead是表头,里面按照不分大小写的userid排列。里面都是loginid,list_prev和list_next以loginid-1作为索引。 hashhead和next构成一个拉链式散列表,hashhead是表头,next是链上下一个。里面也都是loginid,hashead以哈希值作为索引,next以loginid-1作为索引。 其中,hashhead[0]为特殊链表,包含所有空闲的loginid。 number是登录用户数。uptime是上次刷新用户列表的时间,到时间就会扫一遍,剔除异常项。 === UTMPFILE === * 摘自KBS网站 utmpshm 的类型是 UTMPFILE 结构,用来存储登录的状态信息。注意 wwwguest 和这个结构完全没有关系。 这其实也是一块shared memory, key = UTMP_SHMKEY <source lang="C"> #define USHM_SIZE (MAXACTIVE + 10) struct UTMPFILE { struct user_info uinfo[USHM_SIZE]; // 登录状态信息。每个登录都有一个登录号(utmpnum),他就是该登录在 // uinfo 数组中的位置,注意 utmpnum 是 1-based。 }; </source> uinfo 数组的每一个元素都可以用来存储一个登录的状态信息,其结构 user_info 定义: <source lang="C"> struct user_info { /* Structure used in UTMP file */ int active; /* When allocated this field is true */ // 本结构当前是否代表一个登录用户。 int uid; /* Used to find user name in passwd file */ // 登录用户的 uid。 int pid; /* kill() to notify user of talk request */ // telnet 登录表示其进程号。www 登录设置为 1。 int invisible; /* Used by cloaking function in Xyz menu */ // 是否隐身。 int sockactive; /* Used to coordinate talk requests */ int sockaddr; /* ... */ int destuid; /* talk uses this to identify who called */ int mode; /* UL/DL, Talk Mode, Chat Mode, ... */ // 状态,应该赋值为 modes.h 里面的常数。 int pager; /* pager toggle, true, or false */ /* 呼叫器状态,bitwise-OR 以下属性 ALL_PAGER 0x1 FRIEND_PAGER 0x2 ALLMSG_PAGER 0x4 FRIENDMSG_PAGER 0x8 */ int in_chat; /* for in_chat commands */ char chatid[16]; /* chat id, if in chat mode */ char from[IPLEN + 4]; /* machine name the user called in from */ // 登录 IP。 time_t logintime; // 登录时间戳。 int lastpost; // 上次发文的时间戳。 char unused[32]; time_t freshtime; // 上次活动的时间戳,用来计算发呆时间。 int utmpkey; // 登录 key,用于 www cookie 验证保持用户身份。 unsigned int mailbox_prop; /* properties of getCurrentUser()'s mailbox */ // 用户信箱选项,登录时从用户 .mailbox.prop 文件读取,参考 3.3 节 char userid[20]; // 用户名 char realname[20]; // 真实姓名,登录时从用户 userdata 结构读取 char username[40]; // 用户昵称,登录时从 uidshm 共享内存去读取,修改临时昵称就是修改这个字段 int friendsnum; // 好友数量 int friends_uid[MAXFRIENDS]; // 每个好友的 uid,前 friendsnum 个有效。 #ifdef FRIEND_MULTI_GROUP unsigned int friends_p[MAXFRIENDS]; #endif int currentboard; // 当前所在版面的 bid 号 unsigned int mailcheck; /* if have new mail or new msg, stiger */ // 当前登录是否有新信或新消息 }; </source> == utmp.c == ; get_utmpshm_addr() * Utmp.utmpshm ; longlock [(int signo)] * inside Utmp.Lock() ; utmp_lock * Utmp.Lock() ; utmp_unlock [(int fd)] * Utmp.Unlock() ; utmp_setreadonly [(int readonly)] * UtmpHead.SetReadOnly() ; detach_utmp : 仅在WWW中使用。 ; resolve_utmp * Utmp.Init() ; utmp_hash [(const char *userid)] * Utmp.Hash() ; logloop * verify.verifyUtmpHead() : 检测列表是否循环。 ; getnewutmpent [(struct user_info *up)] * Utmp.GetNewUtmpEntry() : 将新建的UserInfo填入空闲的UserInfo中,插入列表和哈希表,增加用户技术等。登录的一部分。 ; getnewutmpent2 [(struct user_info *up)] : 仅在WWW中使用。 ; rebuild_list [(struct user_info *up, char *arg, int p)] * Utmp.RebuildList() '''TODO''' : 重建UtmpHead里的列表。方法是从空的开始一个一个插。 apply_ulist [(APPLY_UTMP_FUNC fptr, void *arg)] apply_ulist_addr [(APPLY_UTMP_FUNC fptr, void *arg)] apply_utmpuid [(APPLY_UTMP_FUNC fptr, int uid, void *arg)] apply_utmp [(APPLY_UTMP_FUNC fptr, int maxcount,const char *userid, void *arg)] search_ulist [(struct user_info *uentp, int (*fptr) (int, struct user_info *), int farg)] ; clear_utmp2 [(int uent)] * Utmp.Clear2() : 清理会话,包括从列表和哈希表删掉,减上站数,清空记录,以及调DoAfterLogout()做收尾工作。 ; clear_utmp [(int uent, int useridx, int pid)] * Utmp.Clear() : 稍作检查,将SHM弄成可写,拿锁,随后调Clear2(),之后防锁,恢复只读。 ; get_utmp_number * UtmpHead.GetNumber() : 拿上站人数 ; get_utmpent [(int utmpnum)] * UserInfo.__init__() ; get_utmpent_num [(struct user_info *uent)] * UserInfo.GetIndex() === 好友相关 === 见[[BBS 好友列表]] cmpfuid [(const void*a,const void*b)] getfriendstr [(struct userec* user,struct user_info* puinfo)] myfriend [(int uid, char *fexp)] hisfriend [(int uid,struct user_info* him)] 02ccc4c4b526fc58dceca8d62e9f6bf1a5ce1e21 BBS 用户信息 0 54 163 147 2012-02-02T23:45:05Z HenryHu 1 wikitext text/x-wiki [[Category:BBS 代码分析]] == User Record == 一个用户的信息,所有登录共用的。 <source lang="c"> struct userec { /* Structure used to hold information in */ char userid[IDLEN + 2]; /* PASSFILE */ char flags; /*一些标志,戒网,版面排序之类的*/ unsigned char title; /*用户级别*/ time_t firstlogin; char lasthost[16]; unsigned int numlogins; unsigned int numposts; #ifdef CONV_PASS char passwd[OLDPASSLEN]; char unused_padding[2]; #endif char username[NAMELEN]; unsigned int club_read_rights[MAXCLUB>>5]; unsigned int club_write_rights[MAXCLUB>>5]; unsigned char md5passwd[MD5PASSLEN]; unsigned userlevel; time_t lastlogin; time_t stay; int signature; unsigned int userdefine[2]; time_t notedate; int noteline; int notemode; time_t exittime; /* 生日数据转移到 userdata 结构中 */ unsigned int usedspace; /* used space of user's mailbox, in bytes */ #ifdef HAVE_USERMONEY int money; int score; char unused[20]; #endif }; struct UCACHE { ucache_hashtable hashtable; ucache_hashtable hashusage; int hashhead[UCACHE_HASHSIZE + 1]; int next[MAXUSERS]; time_t uptime; int number; #ifdef HAVE_CUSTOM_USER_TITLE char user_title[255][USER_TITLE_LEN]; //定义用户的称号字符串。 #endif struct userec passwd[MAXUSERS]; }; static struct UCACHE *uidshm = NULL; </source> == ucache.c == ; ucache_lock ; ucache_unlock [(int fd)] ucache_hashinit ucache_hash_deep [(const char *userid)] ucache_hash [(const char *userid)] fillucache [(struct userec *uentp, int *number, int *prev)] flush_ucache load_ucache ; resolve_ucache * UCache.Init() detach_ucache getuserid [(char *userid, int uid)] setuserid_internal [(int num, const char *userid)] setuserid2 [(int num, const char *userid)] setuserid [(int num, const char *userid)] searchnewuser ; searchuser [(const char *userid)] * UCache.SearchUser() ; getuser [(const char *userid, struct userec **user)] * UCache.GetUser() getuserid2 [(int uid)] u_namearray [(char buf[][IDLEN + 1], int *pnum, char *tag)] getnewuserid3 [(char *userid)] getnewuserid2 [(char *userid)] ; getuserbynum [(int num)] * UCache.GetUserByUid() getnewuserid [(char *userid)] update_user [(struct userec *user, int num, int all)] apply_users [(int (*fptr) (struct userec *, char *), char *arg)] get_giveupinfo [(char* userid,int* basicperm,int s[10][2])] save_giveupinfo [(struct userec* lookupuser,int lcount,int s[10][2])] setcachehomefile [(char* path,const char* user,int unum,char* file)] init_cachedata [(const char* userid,int unum)] flush_cachedata [(const char* userid)] clean_cachedata [(const char* userid,int unum)] do_after_login [(struct userec* user,int unum,int mode)] do_after_logout [(struct userec* user,struct user_info* userinfo,int unum,int mode)] === 自定义User Title相关 === load_user_title flush_user_title get_user_title [(unsigned char titleidx)] set_user_title [(unsigned char titleidx,char* newtitle)] === WWW相关 === longlock [(int signo)] www_guest_lock www_guest_unlock [(int fd)] resolve_guest_table fff9400755f1be59506582415900fceebda5418b 181 163 2012-02-06T04:54:15Z HenryHu 1 /* ucache.c */ wikitext text/x-wiki [[Category:BBS 代码分析]] == User Record == 一个用户的信息,所有登录共用的。 <source lang="c"> struct userec { /* Structure used to hold information in */ char userid[IDLEN + 2]; /* PASSFILE */ char flags; /*一些标志,戒网,版面排序之类的*/ unsigned char title; /*用户级别*/ time_t firstlogin; char lasthost[16]; unsigned int numlogins; unsigned int numposts; #ifdef CONV_PASS char passwd[OLDPASSLEN]; char unused_padding[2]; #endif char username[NAMELEN]; unsigned int club_read_rights[MAXCLUB>>5]; unsigned int club_write_rights[MAXCLUB>>5]; unsigned char md5passwd[MD5PASSLEN]; unsigned userlevel; time_t lastlogin; time_t stay; int signature; unsigned int userdefine[2]; time_t notedate; int noteline; int notemode; time_t exittime; /* 生日数据转移到 userdata 结构中 */ unsigned int usedspace; /* used space of user's mailbox, in bytes */ #ifdef HAVE_USERMONEY int money; int score; char unused[20]; #endif }; struct UCACHE { ucache_hashtable hashtable; ucache_hashtable hashusage; int hashhead[UCACHE_HASHSIZE + 1]; int next[MAXUSERS]; time_t uptime; int number; #ifdef HAVE_CUSTOM_USER_TITLE char user_title[255][USER_TITLE_LEN]; //定义用户的称号字符串。 #endif struct userec passwd[MAXUSERS]; }; static struct UCACHE *uidshm = NULL; </source> == ucache.c == ; ucache_lock ; ucache_unlock [(int fd)] === Hash相关 === ucache_hashinit ucache_hash_deep [(const char *userid)] ; ucache_hash [(const char *userid)] * UCache.Hash() === ucache初始化 === fillucache [(struct userec *uentp, int *number, int *prev)] flush_ucache load_ucache ; resolve_ucache * UCache.Init() detach_ucache === 用户ID相关 === ; getuserid [(char *userid, int uid)] * UserRecord.GetUserId() setuserid_internal [(int num, const char *userid)] setuserid2 [(int num, const char *userid)] setuserid [(int num, const char *userid)] searchnewuser ; searchuser [(const char *userid)] * UCache.SearchUser() ; getuser [(const char *userid, struct userec **user)] * UCache.GetUser() getuserid2 [(int uid)] u_namearray [(char buf[][IDLEN + 1], int *pnum, char *tag)] getnewuserid3 [(char *userid)] getnewuserid2 [(char *userid)] ; getuserbynum [(int num)] * UCache.GetUserByUid() getnewuserid [(char *userid)] update_user [(struct userec *user, int num, int all)] apply_users [(int (*fptr) (struct userec *, char *), char *arg)] get_giveupinfo [(char* userid,int* basicperm,int s[10][2])] save_giveupinfo [(struct userec* lookupuser,int lcount,int s[10][2])] setcachehomefile [(char* path,const char* user,int unum,char* file)] === TMPFS相关 === init_cachedata [(const char* userid,int unum)] flush_cachedata [(const char* userid)] clean_cachedata [(const char* userid,int unum)] === 登录/注销 === ; do_after_login [(struct userec* user,int unum,int mode)] : 不使用TMPFS时可以忽略 ; do_after_logout [(struct userec* user,struct user_info* userinfo,int unum,int mode)] * UCache.DoAfterLogout() '''尚未实现''' : 清理工作 === 自定义User Title相关 === load_user_title flush_user_title get_user_title [(unsigned char titleidx)] set_user_title [(unsigned char titleidx,char* newtitle)] === WWW相关 === longlock [(int signo)] www_guest_lock www_guest_unlock [(int fd)] resolve_guest_table d63aa0c96a9b8cdec746d440b3cfbec7278abae9 分类:BBS 代码分析 14 64 164 2012-02-02T23:45:27Z HenryHu 1 以内容“为了搞出来的东西能和这套shit一样的代码配合工作,首先要研究这坨代码……”创建新页面 wikitext text/x-wiki 为了搞出来的东西能和这套shit一样的代码配合工作,首先要研究这坨代码…… 33c7e49a508a633089968fb072abb69ac163b737 Pybbs 0 56 172 153 2012-02-04T20:21:49Z HenryHu 1 /* XMPP实现 */ wikitext text/x-wiki 基于Python的BBS实现,提供[[BBS数据接口]]。 == XMPP实现 == XMPP阶段: * 认证 ** 基于外部OAuth ** 基于明文 TLS层已经加密了,所以无所谓。'''已实现,见xmppauth.XMPPAuth类''' * 登录 ** 更新用户信息 ** 增加session 已实现。在xmppserver.XMPPServer类中__init__部分。调用Session.Register()进行注册。 * 获取好友列表(roaster) 已实现。在roster.Roster类中。 * 跟踪好友状态并更新好友列表 * 发送消息 * 消息通知 * 接收消息 * 增加好友 * 删除好友 * 修改好友昵称 * 修改状态 c79d301ba353b025710ad70509ceab6bde96bee3 173 172 2012-02-04T20:24:25Z HenryHu 1 /* XMPP实现 */ wikitext text/x-wiki 基于Python的BBS实现,提供[[BBS数据接口]]。 == XMPP实现 == XMPP阶段: * 认证 ** 基于外部OAuth ** 基于明文 :: TLS层已经加密了,所以无所谓。 :: '''已实现''',见xmppauth.XMPPAuth类 * 登录 ** 更新用户信息 ** 增加session :: '''已实现'''。在xmppserver.XMPPServer类中__init__部分。调用Session.Register()进行注册。 * 获取好友列表(roaster) :: '''已实现'''。在roster.Roster类中。 * 跟踪好友状态并更新好友列表 * 发送消息 * 消息通知 * 接收消息 * 增加好友 * 删除好友 * 修改好友昵称 * 修改状态 93e70f547a46e34542b1772164b64c1f6e0304ed 176 173 2012-02-05T04:21:07Z HenryHu 1 /* XMPP实现 */ wikitext text/x-wiki 基于Python的BBS实现,提供[[BBS数据接口]]。 == XMPP实现 == XMPP阶段: * 认证 ** 基于外部OAuth ** 基于明文 :: TLS层已经加密了,所以无所谓。 :: '''已实现''',见xmppauth.XMPPAuth类 * 登录 ** 更新用户信息 ** 增加session :: '''已实现'''。在xmppserver.XMPPServer类中__init__部分。调用Session.Register()进行注册。 * 获取好友列表(roaster) :: '''已实现'''。在roster.Roster类中。 * 跟踪好友状态并更新好友列表 * 发送消息 * 消息通知 * 接收消息 * 增加好友 * 删除好友 * 修改好友昵称 * 修改状态 * 注销 ** 更新用户信息 ** 移除session :: '''已实现'''。用Session.Unregister()。 941c6b63a2cf02614355bd362cb0d293f7af7f64 177 176 2012-02-05T04:50:14Z HenryHu 1 wikitext text/x-wiki 基于Python的BBS实现,提供[[BBS数据接口]]。 == 数据接口实现 == * 登录 ** 用户名/密码登录 :: '''已实现''',考虑安全原因禁用 ** OAuth登录 :: '''部分实现''',只是能用而已…… * 帖子 ** 获取帖子 :: '''已实现''' ** 发帖 ** 同主题上一帖/下一贴 :: '''已实现''' * 版面 ** 获取所有版面列表 :: '''已实现''' * 精华区 * 收藏夹 ** 获取收藏夹列表 :: '''已实现''' * 消息 : 在XMPP接口中实现 * 好友列表 : 在XMPP接口中实现 * 邮箱 == XMPP实现 == XMPP阶段: * 认证 ** 基于外部OAuth ** 基于明文 :: TLS层已经加密了,所以无所谓。 :: '''已实现''',见xmppauth.XMPPAuth类 * 登录 ** 更新用户信息 ** 增加session :: '''已实现'''。在xmppserver.XMPPServer类中__init__部分。调用Session.Register()进行注册。 * 获取好友列表(roaster) :: '''已实现'''。在roster.Roster类中。 * 跟踪好友状态并更新好友列表 * 发送消息 * 消息通知 * 接收消息 * 增加好友 * 删除好友 * 修改好友昵称 * 修改状态 * 注销 ** 更新用户信息 ** 移除session :: '''已实现'''。用Session.Unregister()。 afef97fd1c893c1a107ff6ce4ac54156489e7bae 197 177 2012-02-10T00:49:42Z HenryHu 1 /* XMPP实现 */ wikitext text/x-wiki 基于Python的BBS实现,提供[[BBS数据接口]]。 == 数据接口实现 == * 登录 ** 用户名/密码登录 :: '''已实现''',考虑安全原因禁用 ** OAuth登录 :: '''部分实现''',只是能用而已…… * 帖子 ** 获取帖子 :: '''已实现''' ** 发帖 ** 同主题上一帖/下一贴 :: '''已实现''' * 版面 ** 获取所有版面列表 :: '''已实现''' * 精华区 * 收藏夹 ** 获取收藏夹列表 :: '''已实现''' * 消息 : 在XMPP接口中实现 * 好友列表 : 在XMPP接口中实现 * 邮箱 == XMPP实现 == XMPP阶段: * 认证 ** 基于外部OAuth ** 基于明文 :: TLS层已经加密了,所以无所谓。 :: '''已实现''',见xmppauth.XMPPAuth类 * 登录 ** 更新用户信息 ** 增加session :: '''已实现'''。在xmppserver.XMPPServer类中__init__部分。调用Session.Register()进行注册。 * 获取好友列表(roaster) :: '''已实现'''。在roster.Roster类中。 * 跟踪好友状态并更新好友列表 :: '''已实现'''。在rosters.Rosters类中,包括update_sessions()等 * 发送消息 * 消息通知 * 接收消息 * 增加好友 * 删除好友 * 修改好友昵称 * 修改状态 * 注销 ** 更新用户信息 ** 移除session :: '''已实现'''。用Session.Unregister()。 6e27f3ef2eea45aa68af1016eb8f40e3fcd22630 209 197 2012-02-18T05:29:34Z HenryHu 1 /* XMPP实现 */ wikitext text/x-wiki 基于Python的BBS实现,提供[[BBS数据接口]]。 == 数据接口实现 == * 登录 ** 用户名/密码登录 :: '''已实现''',考虑安全原因禁用 ** OAuth登录 :: '''部分实现''',只是能用而已…… * 帖子 ** 获取帖子 :: '''已实现''' ** 发帖 ** 同主题上一帖/下一贴 :: '''已实现''' * 版面 ** 获取所有版面列表 :: '''已实现''' * 精华区 * 收藏夹 ** 获取收藏夹列表 :: '''已实现''' * 消息 : 在XMPP接口中实现 * 好友列表 : 在XMPP接口中实现 * 邮箱 == XMPP实现 == XMPP阶段: * 认证 ** 基于外部OAuth ** 基于明文 :: TLS层已经加密了,所以无所谓。 :: '''已实现''',见xmppauth.XMPPAuth类 * 登录 ** 更新用户信息 ** 增加session :: '''已实现'''。在xmppserver.XMPPServer类中__init__部分。调用Session.Register()进行注册。 * 好友列表 ** 获取好友列表(roaster) :: '''已实现'''。在roster.Roster类中。 ** 跟踪好友状态并更新好友列表 :: '''已实现'''。在rosters.Rosters类中,包括update_sessions()等 ** 增加好友 ** 删除好友 ** 修改好友昵称 * 消息 ** 发送消息 :: '''已实现'''。参见rosters.Rosters.send_msg() ** 消息通知 :: '''已实现'''。 :: 目前设计为,当收到SIGUSR2,让所有登录用户检查是否有新消息。 ** 接收消息 :: '''已实现'''。保存内部已读索引,每次检查消息,如果有新消息,则发送给用户。 * 修改状态 * 注销 ** 更新用户信息 ** 移除session :: '''已实现'''。用Session.Unregister()。 a5a3343b6fdbc121e8051f3c129ab422c077a9ea 210 209 2012-02-19T01:55:58Z HenryHu 1 /* XMPP实现 */ wikitext text/x-wiki 基于Python的BBS实现,提供[[BBS数据接口]]。 == 数据接口实现 == * 登录 ** 用户名/密码登录 :: '''已实现''',考虑安全原因禁用 ** OAuth登录 :: '''部分实现''',只是能用而已…… * 帖子 ** 获取帖子 :: '''已实现''' ** 发帖 ** 同主题上一帖/下一贴 :: '''已实现''' * 版面 ** 获取所有版面列表 :: '''已实现''' * 精华区 * 收藏夹 ** 获取收藏夹列表 :: '''已实现''' * 消息 : 在XMPP接口中实现 * 好友列表 : 在XMPP接口中实现 * 邮箱 == XMPP实现 == XMPP阶段: * 认证 ** 基于外部OAuth ** 基于明文 :: TLS层已经加密了,所以无所谓。 :: '''已实现''',见xmppauth.XMPPAuth类 * 登录 ** 更新用户信息 ** 增加session :: '''已实现'''。在xmppserver.XMPPServer类中__init__部分。调用Session.Register()进行注册。 * 好友列表 ** 获取好友列表(roaster) :: '''已实现'''。在roster.Roster类中。 ** 跟踪好友状态并更新好友列表 :: '''已实现'''。在rosters.Rosters类中,包括update_sessions()等 ** 增加好友 ** 删除好友 ** 修改好友昵称 * 消息 ** 发送消息 :: '''已实现'''。参见rosters.Rosters.send_msg() ** 消息通知 :: '''已实现'''。 :: 目前设计为,当收到SIGUSR2,让所有登录用户检查是否有新消息。 ** 接收消息 :: '''已实现'''。保存内部已读索引,每次检查消息,如果有新消息,则发送给用户。 * 修改状态 * 扩展 很多成本不大…… 有空搞搞就好了 ** jabber:iq:last :: 上次活动时间(在线)/上次上线时间(下线)/uptime(服务器) ** jabber:iq:version :: 软件版本/系统信息 ** vcard-temp :: 用户信息,例如名字、全名、…… :: '''初步实现''',返回用户名…… ** urn:xmpp:time :: 用户本地时间…… * 注销 ** 更新用户信息 ** 移除session :: '''已实现'''。用Session.Unregister()。 5f2982f4bf938da70722a7d4588bc2c64bc0356c 211 210 2012-02-19T01:57:01Z HenryHu 1 /* XMPP实现 */ wikitext text/x-wiki 基于Python的BBS实现,提供[[BBS数据接口]]。 == 数据接口实现 == * 登录 ** 用户名/密码登录 :: '''已实现''',考虑安全原因禁用 ** OAuth登录 :: '''部分实现''',只是能用而已…… * 帖子 ** 获取帖子 :: '''已实现''' ** 发帖 ** 同主题上一帖/下一贴 :: '''已实现''' * 版面 ** 获取所有版面列表 :: '''已实现''' * 精华区 * 收藏夹 ** 获取收藏夹列表 :: '''已实现''' * 消息 : 在XMPP接口中实现 * 好友列表 : 在XMPP接口中实现 * 邮箱 == XMPP实现 == XMPP阶段: * 认证 ** 基于外部OAuth ** 基于明文 :: TLS层已经加密了,所以无所谓。 :: '''已实现''',见xmppauth.XMPPAuth类 * 登录 ** 更新用户信息 ** 增加session :: '''已实现'''。在xmppserver.XMPPServer类中__init__部分。调用Session.Register()进行注册。 * 好友列表 ** 获取好友列表(roaster) :: '''已实现'''。在roster.Roster类中。 ** 跟踪好友状态并更新好友列表 :: '''已实现'''。在rosters.Rosters类中,包括update_sessions()等 ** 增加好友 ** 删除好友 ** 修改好友昵称 * 消息 ** 发送消息 :: '''已实现'''。参见rosters.Rosters.send_msg() ** 消息通知 :: '''已实现'''。 :: 目前设计为,当收到SIGUSR2,让所有登录用户检查是否有新消息。 ** 接收消息 :: '''已实现'''。保存内部已读索引,每次检查消息,如果有新消息,则发送给用户。 * 修改状态 * 扩展 很多成本不大…… 有空搞搞就好了 ** jabber:iq:last :: 上次活动时间(在线)/上次上线时间(下线)/uptime(服务器) ** jabber:iq:version :: 软件版本/系统信息 ** vcard-temp :: 用户信息,例如名字、全名、…… :: '''初步实现''',返回用户名…… ** urn:xmpp:time :: 用户本地时间…… ** disco#info :: 查询支持的扩展列表。'''已实现''' * 注销 ** 更新用户信息 ** 移除session :: '''已实现'''。用Session.Unregister()。 60be14a9b8044addec32b2c2d0361e79866b8cc5 212 211 2012-02-19T08:44:41Z HenryHu 1 /* XMPP实现 */ wikitext text/x-wiki 基于Python的BBS实现,提供[[BBS数据接口]]。 == 数据接口实现 == * 登录 ** 用户名/密码登录 :: '''已实现''',考虑安全原因禁用 ** OAuth登录 :: '''部分实现''',只是能用而已…… * 帖子 ** 获取帖子 :: '''已实现''' ** 发帖 ** 同主题上一帖/下一贴 :: '''已实现''' * 版面 ** 获取所有版面列表 :: '''已实现''' * 精华区 * 收藏夹 ** 获取收藏夹列表 :: '''已实现''' * 消息 : 在XMPP接口中实现 * 好友列表 : 在XMPP接口中实现 * 邮箱 == XMPP实现 == XMPP阶段: * 认证 ** 基于外部OAuth ** 基于明文 :: TLS层已经加密了,所以无所谓。 :: '''已实现''',见xmppauth.XMPPAuth类 * 登录 ** 更新用户信息 ** 增加session :: '''已实现'''。在xmppserver.XMPPServer类中__init__部分。调用Session.Register()进行注册。 * 好友列表 ** 获取好友列表(roaster) :: '''已实现'''。在roster.Roster类中。 ** 跟踪好友状态并更新好友列表 :: '''已实现'''。在rosters.Rosters类中,包括update_sessions()等 ** 隐身功能 :: '''已实现''',看不见的人,就是看不见…… :: 但是在消息方面有个问题。原来是允许给隐身的人回复消息的,但现在不好判断是否回复,干脆统统不许。 ** 增加好友 ** 删除好友 ** 修改好友昵称 * 消息 ** 发送消息 :: '''已实现'''。参见rosters.Rosters.send_msg() ** 消息通知 :: '''已实现'''。 :: 目前设计为,当收到SIGUSR2,让所有登录用户检查是否有新消息。 ** 接收消息 :: '''已实现'''。保存内部已读索引,每次检查消息,如果有新消息,则发送给用户。 * 修改状态 * 扩展 很多成本不大…… 有空搞搞就好了 ** jabber:iq:last :: 上次活动时间(在线)/上次上线时间(下线)/uptime(服务器) ** jabber:iq:version :: 软件版本/系统信息 ** vcard-temp :: 用户信息,例如名字、全名、…… :: '''初步实现''',返回用户名…… ** urn:xmpp:time :: 用户本地时间…… ** disco#info :: 查询支持的扩展列表。'''已实现''' * 注销 ** 更新用户信息 ** 移除session :: '''已实现'''。用Session.Unregister()。 aeb468262f23439aa9bae0f957dbf9e80c162a87 Cookbook 0 41 178 120 2012-02-05T05:07:25Z HenryHu 1 wikitext text/x-wiki 做过/别人做过的菜列表 * 炒卷心菜 * 炒刀豆 * 炒豆芽 * 干煸四季豆 * 炒青菜 * [[炒土豆丝]] * [[土豆烧刀豆]] * 番茄炒蛋 * 荷包蛋 * [[韭菜炒蛋]] * 可乐鸡块 * 炸鸡块 * 卷心菜炒肉 * 豆芽炒肉 * 茄子炒肉 * 土豆丝炒肉 * [[韭菜炒肉]] 246caf777bf17a5421dd54b5972357aacae3ba87 土豆烧刀豆 0 71 179 2012-02-05T05:11:26Z HenryHu 1 以内容“来源:http://www.chinabaike.com/article/39/food/2007/20071015586878.html == 原料 == * 土豆 几个 * 刀豆 一把 == 配料 == * 酱油 适量 * 盐 一些 * ...”创建新页面 wikitext text/x-wiki 来源:http://www.chinabaike.com/article/39/food/2007/20071015586878.html == 原料 == * 土豆 几个 * 刀豆 一把 == 配料 == * 酱油 适量 * 盐 一些 * 糖 一些 == 准备 == 土豆去皮,切条。用水冲去淀粉。 刀豆去头,切半。 == 制作 == 锅热,加较多油。放土豆,炒至半透明。 加刀豆,炒。 放盐、糖,炒,加水,焖若干分钟。 开盖,加酱油,小火翻炒,出锅。 483cc26e9cec69347b0e8402f96dae54e95e02d0 BBS数据接口 0 76 185 2012-02-09T00:21:49Z HenryHu 1 以内容“== 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | sessi...”创建新页面 wikitext text/x-wiki == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark/deleted/junk |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark/deleted/junk |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} 1e10269fe33c22c805ef94ad23dd541e067703ad 188 185 2012-02-09T00:53:06Z HenryHu 1 /* 列出版面 */ wikitext text/x-wiki == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark/deleted/junk |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark/deleted/junk |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} 71532b0859408443e4ac22eddb23ae27f65cb863 189 188 2012-02-09T00:56:05Z HenryHu 1 /* 获取帖子列表 */ wikitext text/x-wiki == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark/deleted/junk |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark/deleted/junk |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} 9a1e7c0656959ec20566ee669a12a3179e37e2a4 190 189 2012-02-09T01:15:09Z HenryHu 1 /* 获取帖子 */ wikitext text/x-wiki == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark/deleted/junk |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark/deleted/junk |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} 017a8904e2a1c07987e633f26e40c713919aacdf 191 190 2012-02-09T01:16:46Z HenryHu 1 /* 获取附件 */ wikitext text/x-wiki == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark/deleted/junk |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark/deleted/junk |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} 2e7fa4c69969d475a4645ff3e4652ea9489ee671 192 191 2012-02-09T01:19:32Z HenryHu 1 /* 列出收藏夹 */ wikitext text/x-wiki == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark/deleted/junk |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark/deleted/junk |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Board index in favboard>, "binfo": {"name": <string: Board name>, "read": <Boolean: read>, "BM": <string: BMs>, "id": <int: Board ID>, "total": <int: Total post count>, "currentusers": <int: current user count>}, "father": <int: Parent index in favboard>, "type": <string: Type of this entry}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} a179028937ab9db8b72f85dcf4ce768518dc3aef 193 192 2012-02-09T01:19:55Z HenryHu 1 /* 列出收藏夹 */ wikitext text/x-wiki == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark/deleted/junk |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark/deleted/junk |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Board index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} d579173a010c8c0f68b075ecb1be5dc57d5f2f45 194 193 2012-02-09T01:20:21Z HenryHu 1 /* 列出收藏夹 */ wikitext text/x-wiki == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark/deleted/junk |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark/deleted/junk |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} a3f5a93cde6f6ed694f55f0297989c9940530286 BBS OAuth 0 77 186 2012-02-09T00:40:25Z HenryHu 1 以内容“== 登录 == === 显示验证页面 === : '''GET''' /auth/auth {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | redirect_uri || s...”创建新页面 wikitext text/x-wiki == 登录 == === 显示验证页面 === : '''GET''' /auth/auth {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | redirect_uri || string || Redirection URI || No || displaycode |- | response_type || string || ID of the first post to list || No || code |- | client_id || string || Client ID of the client application || No |} === 获取Token === : '''GET''' /auth/token {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | code || string || Authorization code || No |- | redirect_uri || string || Redirection URI, should match with previous requests || No |- | grant_type || string || Type of object to exchange token with || No || authorization_code |- | client_id || string || Client ID of the client application || No |- | client_secret || string || Client secret of the client application || No |} c1953e7f41cc195d33cc43bfa00b15ffe30a2564 187 186 2012-02-09T00:47:53Z HenryHu 1 /* 获取Token */ wikitext text/x-wiki == 登录 == === 显示验证页面 === : '''GET''' /auth/auth {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | redirect_uri || string || Redirection URI || No || displaycode |- | response_type || string || ID of the first post to list || No || code |- | client_id || string || Client ID of the client application || No |} === 获取Token === : '''GET''' /auth/token {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | code || string || Authorization code || No |- | redirect_uri || string || Redirection URI, should match with previous requests || No |- | grant_type || string || Type of object to exchange token with || No || authorization_code |- | client_id || string || Client ID of the client application || No |- | client_secret || string || Client secret of the client application || No |} * Return value ** Success: {"access_token": <string: Token>, "token_type": <string: Token type>} ** Failure: various HTTP error code 8aab3f658dc7b58f3ee319798d7bdd959b637b3d BBS 信息机制 0 49 195 154 2012-02-09T07:51:28Z HenryHu 1 /* libmsg.c */ wikitext text/x-wiki [[Category:BBS 代码分析]] == 数据结构 == === 消息索引 === # msgindex:全消息箱 # msgindex2:收件箱 * 0x00-0x03 4字节 ** 对于收件箱:已读消息个数 * 之后:struct msghead[] ** 对应 MsgHead <source lang="c"> struct msghead { int pos, len; // 消息体在msgcontent中的位置&长度 char sent; // 1: 发送的消息 0: 收到的消息 char mode; // char id[IDLEN+2]; // 发送/接收者ID time_t time; // 发送/接收时间 int frompid, topid; // 发送/接收者进程号 }; </source> == libmsg.c == ; canmsg [(struct userec *fromuser, struct user_info *uin)] * User.CanSendTo() ; can_override [(char *userid, char *whoasks)] : 没人用过…… ; msg_can_sendmsg [(char *userid, int utmppid)] : 没人用过…… ; save_msgtext() * 对应 MsgBox.SaveMsgText() : 把消息存到用户的msgindex与msgcontent文件中。如果是接收到的,也存到msgindex2中。 ; load_msghead() * 对应 MsgBox.LoadMsgHead() : 读出某个消息头,可以指定全消息箱还是收件箱。 ; get_msgcount() * 对应 MsgBox.GetMsgCount() : 获取消息数量。 ; clear_msg() * 对应 MsgBox.ClearMsg() : 清除所有消息 ; get_unreadcount() * 对应 MsgBox.GetUnreadCount() : 获取未读消息数 ; get_unreadmsg() * 对应 MsgBox.GetUnreadMsg() : 从收件箱里获取某条消息,并且修改已读指针。 ; load_msgtext() * 对应 MsgBox.LoadMsgText() : 读取某条消息的内容。 ; sendmsgfunc() : 发送消息。 ; translate_msg() : 转换?目前具体不明 ; mail_msg() : 将所有消息放入邮件寄回信箱。 ; mailbacklastmsg() : 将未发送成功消息寄回信箱。 === SMS支持 === 不在研究范围…… === SQL相关 === 意义不明…… 貌似是通讯录一类的东西 f3ca5d5e03e146f0967c9baca0508819ba99fcc7 196 195 2012-02-10T00:43:43Z HenryHu 1 /* libmsg.c */ wikitext text/x-wiki [[Category:BBS 代码分析]] == 数据结构 == === 消息索引 === # msgindex:全消息箱 # msgindex2:收件箱 * 0x00-0x03 4字节 ** 对于收件箱:已读消息个数 * 之后:struct msghead[] ** 对应 MsgHead <source lang="c"> struct msghead { int pos, len; // 消息体在msgcontent中的位置&长度 char sent; // 1: 发送的消息 0: 收到的消息 char mode; // char id[IDLEN+2]; // 发送/接收者ID time_t time; // 发送/接收时间 int frompid, topid; // 发送/接收者进程号 }; </source> == libmsg.c == ; canmsg [(struct userec *fromuser, struct user_info *uin)] * User.CanSendTo() ; can_override [(char *userid, char *whoasks)] : 没人用过…… ; msg_can_sendmsg [(char *userid, int utmppid)] : 没人用过…… ; save_msgtext() * 对应 MsgBox.SaveMsgText() : 把消息存到用户的msgindex与msgcontent文件中。如果是接收到的,也存到msgindex2中。 ; load_msghead() * 对应 MsgBox.LoadMsgHead() : 读出某个消息头,可以指定全消息箱还是收件箱。 ; get_msgcount() * 对应 MsgBox.GetMsgCount() : 获取消息数量。 ; clear_msg() * 对应 MsgBox.ClearMsg() : 清除所有消息 ; get_unreadcount() * 对应 MsgBox.GetUnreadCount() : 获取未读消息数 ; get_unreadmsg() * 对应 MsgBox.GetUnreadMsg() : 从收件箱里获取某条消息,并且修改已读指针。 ; load_msgtext() * 对应 MsgBox.LoadMsgText() : 读取某条消息的内容。 ; sendmsgfunc() : 发送消息。 ; translate_msg() : 将消息转换为在消息记录之类里面看见的样子 ; mail_msg() : 将所有消息放入邮件寄回信箱。 ; mailbacklastmsg() : 将未发送成功消息寄回信箱。 === SMS支持 === 不在研究范围…… === SQL相关 === 意义不明…… 貌似是通讯录一类的东西 210e623e16489363e00c23cba1302417ab3f686d 207 196 2012-02-16T04:43:13Z HenryHu 1 /* 消息索引 */ wikitext text/x-wiki [[Category:BBS 代码分析]] == 数据结构 == === 消息索引 === # msgindex:全消息箱 # msgindex2:收件箱 * 0x00-0x03 4字节 ** 对于收件箱:已读消息个数 * 之后:struct msghead[] ** 对应 MsgHead <source lang="c"> struct msghead { int pos, len; // 消息体在msgcontent中的位置&长度 char sent; // 1: 发送的消息 0: 收到的消息 char mode; // char id[IDLEN+2]; // 发送/接收者ID time_t time; // 发送/接收时间 int frompid, topid; // 发送/接收者进程号 }; </source> == 发送消息过程分析 == == libmsg.c == ; canmsg [(struct userec *fromuser, struct user_info *uin)] * User.CanSendTo() ; can_override [(char *userid, char *whoasks)] : 没人用过…… ; msg_can_sendmsg [(char *userid, int utmppid)] : 没人用过…… ; save_msgtext() * 对应 MsgBox.SaveMsgText() : 把消息存到用户的msgindex与msgcontent文件中。如果是接收到的,也存到msgindex2中。 ; load_msghead() * 对应 MsgBox.LoadMsgHead() : 读出某个消息头,可以指定全消息箱还是收件箱。 ; get_msgcount() * 对应 MsgBox.GetMsgCount() : 获取消息数量。 ; clear_msg() * 对应 MsgBox.ClearMsg() : 清除所有消息 ; get_unreadcount() * 对应 MsgBox.GetUnreadCount() : 获取未读消息数 ; get_unreadmsg() * 对应 MsgBox.GetUnreadMsg() : 从收件箱里获取某条消息,并且修改已读指针。 ; load_msgtext() * 对应 MsgBox.LoadMsgText() : 读取某条消息的内容。 ; sendmsgfunc() : 发送消息。 ; translate_msg() : 将消息转换为在消息记录之类里面看见的样子 ; mail_msg() : 将所有消息放入邮件寄回信箱。 ; mailbacklastmsg() : 将未发送成功消息寄回信箱。 === SMS支持 === 不在研究范围…… === SQL相关 === 意义不明…… 貌似是通讯录一类的东西 8e3d1b8367f497fd03656c11136267097fe1c8a0 208 207 2012-02-16T05:05:15Z HenryHu 1 /* 发送消息过程分析 */ wikitext text/x-wiki [[Category:BBS 代码分析]] == 数据结构 == === 消息索引 === # msgindex:全消息箱 # msgindex2:收件箱 * 0x00-0x03 4字节 ** 对于收件箱:已读消息个数 * 之后:struct msghead[] ** 对应 MsgHead <source lang="c"> struct msghead { int pos, len; // 消息体在msgcontent中的位置&长度 char sent; // 1: 发送的消息 0: 收到的消息 char mode; // char id[IDLEN+2]; // 发送/接收者ID time_t time; // 发送/接收时间 int frompid, topid; // 发送/接收者进程号 }; </source> == 发送消息过程分析 == <source lang="cpp"> int sendmsgfunc(struct user_info *uentp, const char *msgstr, int mode) { char uident[STRLEN]; struct user_info *uin; struct msghead head, head2; *msgerr = 0; uin = uentp; // uin = 接收者userinfo strcpy(uident, uin->userid); // uident = 接收者userid if (!HAS_PERM(currentuser, PERM_SEECLOAK) && uin->invisible && strcmp(uin->userid, currentuser->userid) && mode != 4) // 若接收者隐身并且我们不能看隐身,并且不是自己发给自己,则不让发 { return -2; } if ((mode != 3) && (LOCKSCREEN == uin->mode)) { /* Leeward 98.02.28 */ // 对方锁屏,不让发 strcpy(msgerr, "对方已经锁定屏幕,请稍候再发或给他(她)写信..."); return -1; } if ((mode != 3) && (false == canIsend2(currentuser,uin->userid))) { /*Haohmaru.06.06.99.检查自己是否被ignore */ // 对方拒绝你的消息,不让发 // canIsend2()在stuff.c // 拒绝列表在ignores文件里 strcpy(msgerr, "对方拒绝接受你的讯息..."); return -1; } if (mode != 3 && uin->mode != WEBEXPLORE) { if (get_unreadcount(uident) > MAXMESSAGE) { // 未读消息太多,不让发 strcpy(msgerr, "对方尚有一些讯息未处理,请稍候再发或给他(她)写信..."); return -1; } } if (msgstr == NULL) { // 木有消息,不让发…… // Comment: 为啥不早查…… return 0; } // 开工构造消息头 // 这个是存接收者那边的…… head.time = time(0); // 发送时间 head.sent = 0; // 接收方消息头 head.mode = mode; // 发送者模式 strncpy(head.id, currentuser->userid, IDLEN+2); // 发送者userid(sent=0) head.frompid = getuinfopid(); // 发送者pid head.topid = uin->pid; // 接收者pid // 这个是存发送者那边的…… memcpy(&head2, &head, sizeof(struct msghead)); // 拷一份,发送者消息头 head2.sent = 1; // 我发的! strncpy(head2.id, uident, IDLEN+2); // 接收者userid(sent=1) // 造好了 // 再查一次用户userinfo…… // t_search()在stuff.c uin = t_search(MsgDesUid, uentp->pid); // 这次查败了,说明接收者跑了,可能是写消息的时候跑的 if ((uin == NULL) || (uin->active == 0) || (uin->pid == 0) || ((kill(uin->pid, 0) != 0) && (uentp->pid != 1)) || strncasecmp(MsgDesUid,uident,STRLEN)) { strcpy(msgerr, "对方已经离线..."); return -1; } // 保存消息 // 消息加到接收者收件箱 if (save_msgtext(uident, &head, msgstr) < 0) return -2; if (strcmp(currentuser->userid, uident)&&mode!=3) { // 如果不是自己发给自己,那就在发送者这边也存一份…… if (save_msgtext(currentuser->userid, &head2, msgstr) < 0) return -2; } if( uin->mode == WWW ){ uin->mailcheck |= CHECK_MSG; return 1; } // 保存完毕 // 消息通知 // 发送SIGUSR2说明有新消息 if (uentp->pid != 1 && kill(uin->pid, SIGUSR2) == -1) { strcpy(msgerr, "对方已经离线....."); return -1; } // 完成! return 1; } </source> == libmsg.c == ; canmsg [(struct userec *fromuser, struct user_info *uin)] * User.CanSendTo() ; can_override [(char *userid, char *whoasks)] : 没人用过…… ; msg_can_sendmsg [(char *userid, int utmppid)] : 没人用过…… ; save_msgtext() * 对应 MsgBox.SaveMsgText() : 把消息存到用户的msgindex与msgcontent文件中。如果是接收到的,也存到msgindex2中。 ; load_msghead() * 对应 MsgBox.LoadMsgHead() : 读出某个消息头,可以指定全消息箱还是收件箱。 ; get_msgcount() * 对应 MsgBox.GetMsgCount() : 获取消息数量。 ; clear_msg() * 对应 MsgBox.ClearMsg() : 清除所有消息 ; get_unreadcount() * 对应 MsgBox.GetUnreadCount() : 获取未读消息数 ; get_unreadmsg() * 对应 MsgBox.GetUnreadMsg() : 从收件箱里获取某条消息,并且修改已读指针。 ; load_msgtext() * 对应 MsgBox.LoadMsgText() : 读取某条消息的内容。 ; sendmsgfunc() : 发送消息。 ; translate_msg() : 将消息转换为在消息记录之类里面看见的样子 ; mail_msg() : 将所有消息放入邮件寄回信箱。 ; mailbacklastmsg() : 将未发送成功消息寄回信箱。 === SMS支持 === 不在研究范围…… === SQL相关 === 意义不明…… 貌似是通讯录一类的东西 b6b6b3a0e290fb55e69f801556c534495b717203 BBS Project 0 78 198 2012-02-11T04:59:53Z HenryHu 1 以内容“构建一个现代化的BBS,吸引新用户使用,提高BBS体验,让各平台下都能够使用BBS。 == API接口 == * [[BBS数据接口]] : 提供BBS各项服...”创建新页面 wikitext text/x-wiki 构建一个现代化的BBS,吸引新用户使用,提高BBS体验,让各平台下都能够使用BBS。 == API接口 == * [[BBS数据接口]] : 提供BBS各项服务的接口。基于HTTP协议,数据格式为JSON。 == 项目 == * [[Pybbs]] : 利用Python实现一个兼容KBS的BBS系统,提供API接口供各个平台下的客户端使用。 * [[Andwell]] : 在API接口的基础上,实现的Android平台下的客户端。 == 相关分析 == * [[:Category:BBS 代码分析]] : 对原有KBS代码的分析,便于开发出兼容于KBS系统的新系统。 4ec7ffbd6e60221f00e22f012d1515ed27fb0284 199 198 2012-02-11T05:06:33Z HenryHu 1 /* API接口 */ wikitext text/x-wiki 构建一个现代化的BBS,吸引新用户使用,提高BBS体验,让各平台下都能够使用BBS。 == API接口 == * [[BBS数据接口]] : 提供BBS各项服务的接口。基于HTTP协议,数据格式为JSON。 * XMPP接口 : 提供另一部分BBS服务的接口,主要包括好友/在线信息/聊天功能。开发中。 : XMPP协议标准见 http://tools.ietf.org/html/rfc6120 以及 http://tools.ietf.org/html/rfc6121 ,具体参见 http://xmpp.org == 项目 == * [[Pybbs]] : 利用Python实现一个兼容KBS的BBS系统,提供API接口供各个平台下的客户端使用。 * [[Andwell]] : 在API接口的基础上,实现的Android平台下的客户端。 == 相关分析 == * [[:Category:BBS 代码分析]] : 对原有KBS代码的分析,便于开发出兼容于KBS系统的新系统。 e120622010d289e53c0bc9abaf096adda82b0562 200 199 2012-02-11T05:08:01Z HenryHu 1 /* API接口 */ wikitext text/x-wiki 构建一个现代化的BBS,吸引新用户使用,提高BBS体验,让各平台下都能够使用BBS。 == API接口 == * [[BBS数据接口]] : 提供BBS各项服务的接口。基于HTTP协议,数据格式为JSON。 * [[BBS XMPP接口]] : 提供另一部分BBS服务的接口,主要包括好友/在线信息/聊天功能。开发中。 : XMPP协议标准见 http://tools.ietf.org/html/rfc6120 以及 http://tools.ietf.org/html/rfc6121 ,具体参见 http://xmpp.org == 项目 == * [[Pybbs]] : 利用Python实现一个兼容KBS的BBS系统,提供API接口供各个平台下的客户端使用。 * [[Andwell]] : 在API接口的基础上,实现的Android平台下的客户端。 == 相关分析 == * [[:Category:BBS 代码分析]] : 对原有KBS代码的分析,便于开发出兼容于KBS系统的新系统。 c7ae17fd427904bff7dab207b92312e4af2898c6 201 200 2012-02-12T07:02:01Z HenryHu 1 /* API接口 */ wikitext text/x-wiki 构建一个现代化的BBS,吸引新用户使用,提高BBS体验,让各平台下都能够使用BBS。 == API接口 == * [[BBS数据接口]] : 提供BBS各项服务的接口。基于HTTP协议,数据格式为JSON。 * [[BBS XMPP接口]] : 提供另一部分BBS服务的接口,主要包括好友/在线信息/聊天功能。 : XMPP协议标准见 http://tools.ietf.org/html/rfc6120 以及 http://tools.ietf.org/html/rfc6121 ,具体参见 http://xmpp.org == 项目 == * [[Pybbs]] : 利用Python实现一个兼容KBS的BBS系统,提供API接口供各个平台下的客户端使用。 * [[Andwell]] : 在API接口的基础上,实现的Android平台下的客户端。 == 相关分析 == * [[:Category:BBS 代码分析]] : 对原有KBS代码的分析,便于开发出兼容于KBS系统的新系统。 e2f74f6882bb985a248db025787554ae293e36ef Git Cheatsheet 0 79 202 2012-02-14T23:10:54Z HenryHu 1 以内容“GIT CHEATSHEET! == 撤销上次 git commit == git reset --soft HEAD 如果你想把add进去的文件也撤销掉,变成没有add的状态: git reset <FILE>”创建新页面 wikitext text/x-wiki GIT CHEATSHEET! == 撤销上次 git commit == git reset --soft HEAD 如果你想把add进去的文件也撤销掉,变成没有add的状态: git reset <FILE> 5998c6a504fd579759feab8ddf1102b2ad11706a 205 202 2012-02-14T23:25:59Z HenryHu 1 /* 撤销上次 git commit */ wikitext text/x-wiki GIT CHEATSHEET! == 撤销上次 git commit == git reset --soft HEAD^ 如果你想把add进去的文件也撤销掉,变成没有add的状态: git reset <FILE> 5a80d0bc19a67a30a90282e129d9bd5066ec283d 206 205 2012-02-14T23:35:22Z HenryHu 1 wikitext text/x-wiki GIT CHEATSHEET! Ref: http://spheredev.org/wiki/Git_for_the_lazy == 撤销上次 git commit == git reset --soft HEAD^ 如果你想把add进去的文件也撤销掉,变成没有add的状态: git reset <FILE> 77a97e35722dfa2fd0a4ace62ec1ae955993e2e2 首页 0 1 203 123 2012-02-14T23:11:41Z HenryHu 1 wikitext text/x-wiki [[SubsConscious]] [[:Category:脚本|Scripts]] [[Package Management]] [[Git Cheatsheet]] <!-- == 入门 == * [http://www.mediawiki.org/wiki/Manual:Configuration_settings MediaWiki 配置设置列表] * [http://www.mediawiki.org/wiki/Manual:FAQ/zh-hans MediaWiki常见问题] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki发布邮件列表] --> 6bc2e695a41e6f5abe2eb85bdc49e654019ce561 204 203 2012-02-14T23:11:59Z HenryHu 1 wikitext text/x-wiki [[SubsConscious]] [[:Category:脚本|Scripts]] [[Package Management]] [[Git Cheatsheet]] [[BBS Project]] <!-- == 入门 == * [http://www.mediawiki.org/wiki/Manual:Configuration_settings MediaWiki 配置设置列表] * [http://www.mediawiki.org/wiki/Manual:FAQ/zh-hans MediaWiki常见问题] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki发布邮件列表] --> 1b72f927b16d8d463b2f172ad2cd510101f9f6fa BBS XMPP接口 0 80 213 2012-02-21T17:48:40Z HenryHu 1 以内容“== 设计问题 == === 消息通知 === 之前#的消息系统: * 每个用户一个消息箱 * 消息箱自带未读计数 * 消息靠SIGUSR2通知 * 接收方有...”创建新页面 wikitext text/x-wiki == 设计问题 == === 消息通知 === 之前#的消息系统: * 每个用户一个消息箱 * 消息箱自带未读计数 * 消息靠SIGUSR2通知 * 接收方有通知计数 * 每个计数需要一次回车 * 只能给特定登录发送消息 * 消息内有目标登录 ** 查看消息时,略过目标不是本登录的消息 对于XMPP,无法确定应发给哪个登录 * 通知所有登录 消息发送过程: * 查看是否能发 * 投递消息 * 通知新消息 故,XMPP情况下: * 有一个登录能发,则认为能发 * 投递消息和登录无关,这个和原来一样 * 通知所有登录有新消息 但是,通知方面: * 如果每条消息需要一次回车,则在有XMPP情况下,普通登录均为无用回车 所以修改: * 若有消息未处理则不通知 导致问题: * 若只有普通登录无XMPP登录,则只通知一次导致接收方只能弹出一条消息 修改: * 若只有普通登录,则 ** 对于消息目标登录,发送多个通知 ** 对于其他登录,发送1个通知 cb8d35ab87546df5e7d55a2e2a9bddb3f3a5ecb3 214 213 2012-02-22T06:53:51Z HenryHu 1 /* 消息通知 */ wikitext text/x-wiki == 设计问题 == === 消息通知 === 之前#的消息系统: * 每个用户一个消息箱 * 消息箱自带未读计数 * 消息靠SIGUSR2通知 * 接收方有通知计数 * 每个计数需要一次回车 * 只能给特定登录发送消息 * 消息内有目标登录 ** 查看消息时,略过目标不是本登录的消息 对于XMPP,无法确定应发给哪个登录 * 通知所有登录 消息发送过程: * 查看是否能发 * 投递消息 * 通知新消息 故,XMPP情况下: * 有一个登录能发,则认为能发 * 投递消息和登录无关,这个和原来一样 * 通知所有登录有新消息 但是,通知方面: * 如果每条消息需要一次回车,则在有XMPP情况下,普通登录均为无用回车 所以修改: * 若有消息未处理则不通知 导致问题: * 若只有普通登录无XMPP登录,则只通知一次导致接收方只能弹出一条消息 修改: * 若只有普通登录,则 ** 对于消息目标登录,发送多个通知 ** 对于其他登录,发送1个通知 ** 其实我不知道这是第几个通知…… 目前是如果已经在消息状态了那就不是第一条,否则是第一条…… c7cfbb56a4a18ed363af95bd1ff65427dc9653b9 Headphone 0 81 215 2012-03-29T23:19:37Z HenryHu 1 以内容“耳机列表 * Philips ? 紫日金利(大概)买的某飞利浦耳塞式耳机。 * Philips SHE4500 耳塞造型奇特的耳塞式耳机。带着比较舒服,...”创建新页面 wikitext text/x-wiki 耳机列表 * Philips ? 紫日金利(大概)买的某飞利浦耳塞式耳机。 * Philips SHE4500 耳塞造型奇特的耳塞式耳机。带着比较舒服,不过清洁工作比较难做。 * Sennheiser HD201 Lightweight Over-Ear Binaural Headphones 家里用的头戴式大耳机。挺轻的,就我来说,音质不错…… * Panasonic RP-HT21 Lightweight Headphones with XBS Port 250ded20657068d375e6464e2c7458711bc010f9 Headphone 0 81 216 215 2012-03-29T23:22:45Z HenryHu 1 wikitext text/x-wiki 耳机列表 * Philips ? 紫日金利(大概)买的某飞利浦耳塞式耳机。 * Philips SHE4500 耳塞造型奇特的耳塞式耳机。带着比较舒服,不过清洁工作比较难做。 * JLab J3M Micro Atomic In-Ear Earphones with Microphone - Jet Black ** 价格: 21.72$ 某次的Amazon Deal,第一个入耳式耳机,应该是Black Friday买的。感觉很糟糕,带着有种压迫感,可能是因为还不习惯入耳式的关系。可能是由于阻抗小,插上手机能够听见明显白噪音…… 优点是有话筒和线控,能用来打电话。不过终究还是换了别的。 * Sennheiser HD201 Lightweight Over-Ear Binaural Headphones ** 价格: 16.32$ 家里用的头戴式大耳机。挺轻的,就我来说,音质不错…… * Panasonic RP-HT21 Lightweight Headphones with XBS Port ** 价格: 4.49$ 3daa2bf337aa66e28b6b07d6b98a042a7012e41c 217 216 2012-04-05T21:17:30Z HenryHu 1 wikitext text/x-wiki 耳机列表 * Philips ? 紫日金利(大概)买的某飞利浦耳塞式耳机。 * Philips SHE4500 耳塞造型奇特的耳塞式耳机。带着比较舒服,不过清洁工作比较难做。 * JLab J3M Micro Atomic In-Ear Earphones with Microphone - Jet Black ** 价格: 21.72$ 某次的Amazon Deal,第一个入耳式耳机,应该是Black Friday买的。感觉很糟糕,带着有种压迫感,可能是因为还不习惯入耳式的关系。可能是由于阻抗小,插上手机能够听见明显白噪音…… 优点是有话筒和线控,能用来打电话。不过终究还是换了别的。 * Sennheiser HD201 Lightweight Over-Ear Binaural Headphones ** 价格: 16.32$ 家里用的头戴式大耳机。挺轻的,就我来说,音质不错…… * Panasonic RP-HT21 Lightweight Headphones with XBS Port ** 价格: 4.49$ 的确是lightweight,好轻,只有47克…… 以轻度压力夹在头上,到目前为止都戴着很舒服,没啥感觉基本上。 音质嘛就那样,那个XBS Port是Extra Bass System,貌似低音部分比较强一些? 8a87f1cf3d4de76d6864c674b4a134e93a3ac5a8 Git Cheatsheet 0 79 218 206 2012-04-12T20:09:28Z HenryHu 1 wikitext text/x-wiki GIT CHEATSHEET! Ref: http://spheredev.org/wiki/Git_for_the_lazy Ref: https://makandracards.com/makandra/topics/version-control == 撤销上次 git commit == git reset --soft HEAD^ 如果你想把add进去的文件也撤销掉,变成没有add的状态: git reset <FILE> == 删除branch == 删除本地branch: git branch -d <branch name> 这个不会对远程的产生影响。只是你push/pull的时候,这个branch不会参与。 如果要删除远程branch: '''注意!注意!危险!''' git push origin :<branch name> 这样远端这个branch会被干掉…… 6c8c2e21848c44ed233664227cd6e60f3412a48f Latex notes 0 82 219 2012-05-12T07:18:17Z HenryHu 1 以内容“Some notes about formatting latex documents. [[Latex:Source code]]”创建新页面 wikitext text/x-wiki Some notes about formatting latex documents. [[Latex:Source code]] b309b1647b8a842c5d74d179134ce3b7a12e6c30 Latex:Source code 0 83 220 2012-05-12T07:21:37Z HenryHu 1 以内容“How to insert source code into a latex document. == listings == First method: use listings package === Package === <source lang="latex"> \usepackage{listings} </sourc...”创建新页面 wikitext text/x-wiki How to insert source code into a latex document. == listings == First method: use listings package === Package === <source lang="latex"> \usepackage{listings} </source> === Usage === <source lang=latex> \lstset{language=c} \lstset{caption=Some caption} \lstset{captionpos=b} // caption at bottom, default to top \lstinputlisting{some source code.c} </source> For short code: <source lang=latex> \begin{lstlisting} Your source code here \end{lstlisting} </source> c2aa4abf169931212d206ba4ee63cbd3aa391664 221 220 2012-05-12T07:22:03Z HenryHu 1 /* Usage */ wikitext text/x-wiki How to insert source code into a latex document. == listings == First method: use listings package === Package === <source lang="latex"> \usepackage{listings} </source> === Usage === <source lang=latex> \lstset{language=c} \lstset{caption=Some caption} \lstset{captionpos=b} % caption at bottom, default to top \lstinputlisting{some source code.c} </source> For short code: <source lang=latex> \begin{lstlisting} Your source code here \end{lstlisting} </source> f763f864cb0420ccd7d1dcf896f9836a62892c87 TERM 0 84 222 2012-05-23T21:00:25Z HenryHu 1 以内容“TERM变量,terminfo 与 termcap == TERM == 一个环境变量,表示当前用那个terminfo/termcap == termcap == 这东西已经过时了 == terminfo == 某人...”创建新页面 wikitext text/x-wiki TERM变量,terminfo 与 termcap == TERM == 一个环境变量,表示当前用那个terminfo/termcap == termcap == 这东西已经过时了 == terminfo == 某人重写termcap之后的结果。 其实是一个数据库,用$TERM作为索引进去找。每个项目描述了某种terminal,例如rxvt-unicode,screen-256color之类。 在linux下,在/usr/share/terminfo/?/里面有所有的数据。文件名就是key。 不过这个东西是二进制的。幸好有东西可以编解码。 * 反编译: 用[[infocmp]] * 编译: 用[[tic]] 转成文本形式之后,这个的内容是一堆a=b形式的键-值对,或者就一个键名,或者a#b,逗号分隔。 其中,键名表示了某种功能/能力。如果只有一个键名,那就是有一种能力。如果有值,那就是输出那堆值之后,能够使用的某种能力,或者term拿到那堆值之后,说明你按了某个键。 如果是a#b,那就是某个属性和对应值。 '''能力列表参见terminfo manpage。Capname那列就是能力名字。''' === 测试是否有能力 === tput <capname> 如果返回值是0,那就是有这个能力。返回1,就木有那个能力。返回4,说明你打错能力名了。 例如 tput xenl 我这儿返回0,说明我的term在80行之后忽略换行(啥?)。类似的还有bce,bw,……一堆。 === 获得属性值 === tput <capname> 输出的就是属性值。 例如 tput colors 就会得到当前term支持的颜色数量。例如在我这儿是256。 类似的有cols(列数), lines(行数),…… === 使用能力 === tput <capname> [<param1>, ...] 比如说: tput smul; echo xxxx; tput enul 就是使用了进入下划线模式(smul)和退出下划线模式(enul)。你可以看见xxxx是带下划线的。 类似的有bold(粗体), cud, cuf, ... * cub, cud, cuf, cuu: 左移$1列,下移$1行,右移$1列,上移$1行。 * cub1, cud1, cuf1, cuu1: 以上命令的1-简化版本。 * sc, rc: 保存当前光标位置, * civis, cvvis, cnorm: 隐藏光标,突出光标(very visible!), 恢复正常光标 * blink: 闪烁模式 * clear: 清屏 * dl: 删$1行。 === 获得按键说明 === 这个其实是给各种库用的。比如你拿到一堆转义序列,你不知道是哪个键。这时候,看terminfo就能知道。 例如,你看infocmp结果里,有khome=xxx。那就是说,拿到xxx这个序列,就是按了home键。 所以有时候你登录到远端主机,发现home/end不好用,就是这个的关系。一般是因为,远端的主机没有你的terminal的terminfo数据。这样,他就不知道home/end对应的序列是啥了。这样,你按了home/end他也不懂。 解决方法也很简单,只要把你登录过去看见的$TERM对应的terminfo文件复制到远端的正确位置,就行了。对面有了terminfo数据,也就能理解这个序列代表哪个键了。 9db2c8f94eaaa1279bf2e3aa65f420fe04d61353 223 222 2012-05-23T21:11:13Z HenryHu 1 /* 使用能力 */ wikitext text/x-wiki TERM变量,terminfo 与 termcap == TERM == 一个环境变量,表示当前用那个terminfo/termcap == termcap == 这东西已经过时了 == terminfo == 某人重写termcap之后的结果。 其实是一个数据库,用$TERM作为索引进去找。每个项目描述了某种terminal,例如rxvt-unicode,screen-256color之类。 在linux下,在/usr/share/terminfo/?/里面有所有的数据。文件名就是key。 不过这个东西是二进制的。幸好有东西可以编解码。 * 反编译: 用[[infocmp]] * 编译: 用[[tic]] 转成文本形式之后,这个的内容是一堆a=b形式的键-值对,或者就一个键名,或者a#b,逗号分隔。 其中,键名表示了某种功能/能力。如果只有一个键名,那就是有一种能力。如果有值,那就是输出那堆值之后,能够使用的某种能力,或者term拿到那堆值之后,说明你按了某个键。 如果是a#b,那就是某个属性和对应值。 '''能力列表参见terminfo manpage。Capname那列就是能力名字。''' === 测试是否有能力 === tput <capname> 如果返回值是0,那就是有这个能力。返回1,就木有那个能力。返回4,说明你打错能力名了。 例如 tput xenl 我这儿返回0,说明我的term在80行之后忽略换行(啥?)。类似的还有bce,bw,……一堆。 === 获得属性值 === tput <capname> 输出的就是属性值。 例如 tput colors 就会得到当前term支持的颜色数量。例如在我这儿是256。 类似的有cols(列数), lines(行数),…… === 使用能力 === tput <capname> [<param1>, ...] 比如说: tput smul; echo xxxx; tput enul 就是使用了进入下划线模式(smul)和退出下划线模式(enul)。你可以看见xxxx是带下划线的。 类似的有bold(粗体), cud, cuf, ... * cub, cud, cuf, cuu: 左移$1列,下移$1行,右移$1列,上移$1行。 * cub1, cud1, cuf1, cuu1: 以上命令的1-简化版本。 * cup: 直接跳转到$1行$1列 * sc, rc: 保存,恢复当前光标位置(这不是栈……) * civis, cvvis, cnorm: 隐藏光标,突出光标(very visible!), 恢复正常光标 * blink: 闪烁模式 * clear: 清屏 * dl: 删$1行。 * setab, setaf: 设置背景色,设置前景色。 * rev: 反色。 === 获得按键说明 === 这个其实是给各种库用的。比如你拿到一堆转义序列,你不知道是哪个键。这时候,看terminfo就能知道。 例如,你看infocmp结果里,有khome=xxx。那就是说,拿到xxx这个序列,就是按了home键。 所以有时候你登录到远端主机,发现home/end不好用,就是这个的关系。一般是因为,远端的主机没有你的terminal的terminfo数据。这样,他就不知道home/end对应的序列是啥了。这样,你按了home/end他也不懂。 解决方法也很简单,只要把你登录过去看见的$TERM对应的terminfo文件复制到远端的正确位置,就行了。对面有了terminfo数据,也就能理解这个序列代表哪个键了。 202b2b9d6aea3ee44a836ef48552ca6a2703f4e0 BBS数据接口 0 76 224 194 2012-05-27T22:22:47Z HenryHu 1 /* 帖子 */ wikitext text/x-wiki == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark/deleted/junk |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark/deleted/junk |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || '''normal'''/digest/mark/deleted/junk |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || '''normal'''/digest/mark/deleted/junk |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} b820e9eb85f7afbdeb62de2971999dad0b245d5c 226 224 2012-05-28T19:34:14Z HenryHu 1 /* 获取帖子 */ wikitext text/x-wiki == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark/deleted/junk |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark/deleted/junk |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || '''normal'''/digest/mark/deleted/junk |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || '''normal'''/digest/mark/deleted/junk |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} a6c813436245e937fc4e0c56f3ba0cf6b13605b4 227 226 2012-05-28T19:34:51Z HenryHu 1 /* 获取帖子列表 */ wikitext text/x-wiki == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark/deleted/junk |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark/deleted/junk |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || '''normal'''/digest/mark/deleted/junk |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || '''normal'''/digest/mark/deleted/junk |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} 479c3a6c46b3f13b18f48865361aa21c6312abe4 233 227 2012-06-01T04:43:47Z HenryHu 1 /* 获取附件 */ wikitext text/x-wiki == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark/deleted/junk |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark/deleted/junk |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || '''normal'''/digest/mark/deleted/junk |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || '''normal'''/digest/mark/deleted/junk |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} 91dfa984a2922cb66d6d902aacefed3e6eb9173e 234 233 2012-06-01T04:44:11Z HenryHu 1 /* 同主题浏览 */ wikitext text/x-wiki == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark/deleted/junk |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark/deleted/junk |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || '''normal'''/digest/mark/deleted/junk |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || '''normal'''/digest/mark/deleted/junk |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} 3fdf2444ed53abe78d243666e779326646be2065 235 234 2012-06-01T04:51:07Z HenryHu 1 /* 获取帖子列表 */ wikitext text/x-wiki == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark/deleted/junk |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || '''normal'''/digest/mark/deleted/junk |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || '''normal'''/digest/mark/deleted/junk |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} a1b6ed3f300265399291711769abeb44f478d15d 236 235 2012-06-01T04:51:18Z HenryHu 1 /* 获取附件 */ wikitext text/x-wiki == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || '''normal'''/digest/mark/deleted/junk |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || '''normal'''/digest/mark/deleted/junk |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} 262cb216f6a46c6a8bbdd88a477a89a335bb3efd 237 236 2012-06-05T06:25:26Z HenryHu 1 /* 引用帖子 */ wikitext text/x-wiki == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || '''normal'''/digest/mark |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || '''normal'''/digest/mark/deleted/junk |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} 182a873c49fee82fcab7dd6eb6a2e7281caa58e0 238 237 2012-06-05T06:25:47Z HenryHu 1 /* 发帖/回帖 */ wikitext text/x-wiki == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || '''normal'''/digest/mark |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || '''normal'''/digest/mark |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} ba4f1a98d9085fff878c7a4fc48d139c6f46e24f 239 238 2012-06-05T18:52:16Z HenryHu 1 wikitext text/x-wiki == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || '''normal'''/digest/mark |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || '''normal'''/digest/mark |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} cfe28240d933211a4b544727054ddae00566a7ef 240 239 2012-06-11T16:44:21Z HenryHu 1 /* 同主题浏览 */ wikitext text/x-wiki == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || '''normal'''/digest/mark |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || '''normal'''/digest/mark |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} 8b614bd5a0acd1307010e9628041f1a898bca70f 241 240 2012-06-16T19:05:25Z HenryHu 1 /* 发帖/回帖 */ wikitext text/x-wiki == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || '''normal'''/digest/mark |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || '''normal'''/digest/mark |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |} result: {"error": {<string: error 1>: 1}} 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || '''normal'''/digest/mark |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} 6ab9c249d1559eaf4d86b0841b6a27e3d69a8127 242 241 2012-06-16T19:20:21Z HenryHu 1 /* 列出版面 */ wikitext text/x-wiki == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "output": <string: may output>, "desc": <string: description>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || '''normal'''/digest/mark |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || '''normal'''/digest/mark |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |} result: {"error": {<string: error 1>: 1}} 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || '''normal'''/digest/mark |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} 23ef4ed4ed8dca168d1f014915368f65569c68fa 243 242 2012-06-16T19:21:15Z HenryHu 1 /* 准备 */ wikitext text/x-wiki == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "output": <string: may output>, "desc": <string: description>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || '''normal'''/digest/mark |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || '''normal'''/digest/mark |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |} result: {"error": {<string: error 1>: 1}} 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || '''normal'''/digest/mark |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} ebda5c0b6a5dfe981513669791ea752fb3155121 244 243 2012-06-19T18:11:33Z HenryHu 1 /* 列出版面 */ wikitext text/x-wiki == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || '''normal'''/digest/mark |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || '''normal'''/digest/mark |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |} result: {"error": {<string: error 1>: 1}} 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || '''normal'''/digest/mark |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} 21bb689ebde89d61a7e52822f7420e9d95ea0948 247 244 2012-06-22T20:46:04Z HenryHu 1 /* 会话 */ wikitext text/x-wiki == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || '''normal'''/digest/mark |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || '''normal'''/digest/mark |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |} result: {"error": {<string: error 1>: 1}} 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || '''normal'''/digest/mark |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query || No |} f73215def7cf3aa5af956f490f2402fedc12381d 248 247 2012-06-25T18:22:38Z HenryHu 1 /* 准备 */ wikitext text/x-wiki == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || '''normal'''/digest/mark |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || '''normal'''/digest/mark |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |} result: {"error": {<string: error>: 1}} 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || '''normal'''/digest/mark |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query || No |} 33a9d6106b1ecf35e4a004d37812a48187ebb84a 249 248 2012-06-25T18:58:59Z HenryHu 1 /* 获取帖子列表 */ wikitext text/x-wiki == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。 == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || '''normal'''/digest/mark |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || '''normal'''/digest/mark |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |} result: {"error": {<string: error>: 1}} 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || '''normal'''/digest/mark |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query || No |} 61a91ea01ae5de3b20ab2e6caf9709a2b6458531 250 249 2012-06-25T19:09:05Z HenryHu 1 /* 获取用户信息 */ wikitext text/x-wiki == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。 == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || '''normal'''/digest/mark |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || '''normal'''/digest/mark |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |} result: {"error": {<string: error>: 1}} 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || '''normal'''/digest/mark |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: {"signature_id": <int: default signature id>} f52b7d95b749921b65613b4532c937b6c0c98e1c 251 250 2012-06-25T22:23:29Z HenryHu 1 /* 版面 */ wikitext text/x-wiki == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** zhiding: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || '''normal'''/digest/mark |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。 == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || '''normal'''/digest/mark |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || '''normal'''/digest/mark |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || '''normal'''/digest/mark |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |} result: {"error": {<string: error>: 1}} 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || '''normal'''/digest/mark |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: {"signature_id": <int: default signature id>} 0780961faca8598499812ab183be4e60bee3dc01 252 251 2012-06-25T22:24:52Z HenryHu 1 wikitext text/x-wiki == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** zhiding: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。 == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |} result: {"error": {<string: error>: 1}} 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: {"signature_id": <int: default signature id>} 8424cf9d93d716c318785114cc9885b6570e5d97 253 252 2012-06-26T17:35:42Z HenryHu 1 /* 版面 */ wikitext text/x-wiki == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。 == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |} result: {"error": {<string: error>: 1}} 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: {"signature_id": <int: default signature id>} bb58de0d5949ee3d13920dbf750caab90c2fe100 259 253 2012-07-06T20:25:19Z HenryHu 1 /* 会话 */ wikitext text/x-wiki == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。 == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |} result: {"error": {<string: error>: 1}} 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, 'content': <string: content of the post>, 'picattach': [ <AttachmentInfo: information of one attachment>, ... ], 'otherattach': [ <AttachmentInfo: information of one attachment>, ... ] } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: {"signature_id": <int: default signature id>} db04b8d1e4552a3791706956022c13bc5932391f 260 259 2012-07-06T20:25:47Z HenryHu 1 /* 获取默认签名档编号 */ wikitext text/x-wiki == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。 == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: {"picattach": [{"name": <string: Attachment filename>, "offset:": <int: Attachment offset in post>}, {...}...], "title": <string: Post title>, "content": <string: Post content>, "otherattach": [{...}...], "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID>} === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |} result: {"error": {<string: error>: 1}} 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, 'content': <string: content of the post>, 'picattach': [ <AttachmentInfo: information of one attachment>, ... ], 'otherattach': [ <AttachmentInfo: information of one attachment>, ... ] } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> 76eea2f95fdbd06fe8a22a27ae461efade97c830 261 260 2012-07-06T20:29:47Z HenryHu 1 /* 获取帖子 */ wikitext text/x-wiki == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。 == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "title": <string: Post title>, "content": <string: Post content>, "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |} result: {"error": {<string: error>: 1}} 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, 'content': <string: content of the post>, 'picattach': [ <AttachmentInfo: information of one attachment>, ... ], 'otherattach': [ <AttachmentInfo: information of one attachment>, ... ] } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> 3adbe69069a7d94da84d3aaa0e05e8fe75b5c345 262 261 2012-07-06T20:30:14Z HenryHu 1 /* JSONP */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>},{...}...] === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。 == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "title": <string: Post title>, "content": <string: Post content>, "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |} result: {"error": {<string: error>: 1}} 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, 'content': <string: content of the post>, 'picattach': [ <AttachmentInfo: information of one attachment>, ... ], 'otherattach': [ <AttachmentInfo: information of one attachment>, ... ] } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> c56308bb9ccb07d88875b5c17d77dbdc841353ec 263 262 2012-07-06T20:31:39Z HenryHu 1 /* 列出版面 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>}, {...}...] === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。 == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "title": <string: Post title>, "content": <string: Post content>, "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |} result: {"error": {<string: error>: 1}} 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, 'content': <string: content of the post>, 'picattach': [ <AttachmentInfo: information of one attachment>, ... ], 'otherattach': [ <AttachmentInfo: information of one attachment>, ... ] } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> d8a6d5acf7f0628d450a2e894e7d6ed61eceadfb 264 263 2012-07-06T20:33:19Z HenryHu 1 /* 版面 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>} } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。 == 帖子 == === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "title": <string: Post title>, "content": <string: Post content>, "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value ** {"content": <string: Post content encoded in Base64>, "name": <string: Attachment name>} === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** {"title": <string: Quoted title>, "content": <string: Quoted content>} === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |} result: {"error": {<string: error>: 1}} 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, 'content': <string: content of the post>, 'picattach': [ <AttachmentInfo: information of one attachment>, ... ], 'otherattach': [ <AttachmentInfo: information of one attachment>, ... ] } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> 320519064a39f6376e1e848e918b15f2771efd68 265 264 2012-07-06T20:34:59Z HenryHu 1 /* 帖子 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>} } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。 == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID> } </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "title": <string: Post title>, "content": <string: Post content>, "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: [{"index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry>}, {...}...] == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, 'content': <string: content of the post>, 'picattach': [ <AttachmentInfo: information of one attachment>, ... ], 'otherattach': [ <AttachmentInfo: information of one attachment>, ... ] } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> 24f049e498638dc9f07606c726313a2056047eb6 AndWell 0 85 225 2012-05-28T17:40:48Z HenryHu 1 以内容“=== Change Log === 0.2.5 * Various bug fix * Enhancement: Only refresh post list if necessary 0.2.4 * Enhancement: Persist connection 0.2.3 * Enhancement: Reply in vi...”创建新页面 wikitext text/x-wiki === Change Log === 0.2.5 * Various bug fix * Enhancement: Only refresh post list if necessary 0.2.4 * Enhancement: Persist connection 0.2.3 * Enhancement: Reply in view mode * Enhancement: Icons * Enhancement: Insert banner 0.2.2 * Bug fix: Stale busy dialog 0.2.1 * Enhancement: Show busy dialog when posting / replying * Enhancement: Save last qmd# 0.2 * New feature: Post * New feature: Reply 0.1.8 * Minor fix to support Google TV 0.1.7 * Minor modification to UI 0.1.6 * Initial release on the market * Require users to enter server's API address. 219284c07d515e57953031ec9498f863f85be8d4 228 225 2012-05-28T23:37:08Z HenryHu 1 /* Change Log */ wikitext text/x-wiki === Change Log === 0.2.6 * Limit timeout 0.2.5 * Various bug fix * Enhancement: Only refresh post list if necessary 0.2.4 * Enhancement: Persist connection 0.2.3 * Enhancement: Reply in view mode * Enhancement: Icons * Enhancement: Insert banner 0.2.2 * Bug fix: Stale busy dialog 0.2.1 * Enhancement: Show busy dialog when posting / replying * Enhancement: Save last qmd# 0.2 * New feature: Post * New feature: Reply 0.1.8 * Minor fix to support Google TV 0.1.7 * Minor modification to UI 0.1.6 * Initial release on the market * Require users to enter server's API address. 0e16c2db52f726af8c2eb6f6bd6b9b767651808f 229 228 2012-05-29T04:17:01Z HenryHu 1 /* Change Log */ wikitext text/x-wiki === Change Log === 0.2.8 * Thread first 0.2.7 * Fix unread mark 0.2.6 * Limit timeout 0.2.5 * Various bug fix * Enhancement: Only refresh post list if necessary 0.2.4 * Enhancement: Persist connection 0.2.3 * Enhancement: Reply in view mode * Enhancement: Icons * Enhancement: Insert banner 0.2.2 * Bug fix: Stale busy dialog 0.2.1 * Enhancement: Show busy dialog when posting / replying * Enhancement: Save last qmd# 0.2 * New feature: Post * New feature: Reply 0.1.8 * Minor fix to support Google TV 0.1.7 * Minor modification to UI 0.1.6 * Initial release on the market * Require users to enter server's API address. f810b86b9b4a05f151fc07f3ea1423bb3d4075bc 230 229 2012-05-29T04:17:57Z HenryHu 1 [[Andwell]]移动到[[AndWell]] wikitext text/x-wiki === Change Log === 0.2.8 * Thread first 0.2.7 * Fix unread mark 0.2.6 * Limit timeout 0.2.5 * Various bug fix * Enhancement: Only refresh post list if necessary 0.2.4 * Enhancement: Persist connection 0.2.3 * Enhancement: Reply in view mode * Enhancement: Icons * Enhancement: Insert banner 0.2.2 * Bug fix: Stale busy dialog 0.2.1 * Enhancement: Show busy dialog when posting / replying * Enhancement: Save last qmd# 0.2 * New feature: Post * New feature: Reply 0.1.8 * Minor fix to support Google TV 0.1.7 * Minor modification to UI 0.1.6 * Initial release on the market * Require users to enter server's API address. f810b86b9b4a05f151fc07f3ea1423bb3d4075bc 232 230 2012-05-30T07:11:39Z HenryHu 1 /* Change Log */ wikitext text/x-wiki === Change Log === 0.2.9 * Bug fix: release connection for reuse 0.2.8 * Thread first 0.2.7 * Fix unread mark 0.2.6 * Limit timeout 0.2.5 * Various bug fix * Enhancement: Only refresh post list if necessary 0.2.4 * Enhancement: Persist connection 0.2.3 * Enhancement: Reply in view mode * Enhancement: Icons * Enhancement: Insert banner 0.2.2 * Bug fix: Stale busy dialog 0.2.1 * Enhancement: Show busy dialog when posting / replying * Enhancement: Save last qmd# 0.2 * New feature: Post * New feature: Reply 0.1.8 * Minor fix to support Google TV 0.1.7 * Minor modification to UI 0.1.6 * Initial release on the market * Require users to enter server's API address. ede716efac908bae70fc7941dab2e3714fd6f6b5 Andwell 0 86 231 2012-05-29T04:17:57Z HenryHu 1 [[Andwell]]移动到[[AndWell]] wikitext text/x-wiki #REDIRECT [[AndWell]] 5d0cf98d900b6a50a1aa003cfa56f102f6a56f80 Video Decoding 0 87 245 2012-06-21T17:58:46Z HenryHu 1 以内容“== Xoom == === H264 === BubbleUPnP, MoboPlayer 864x480, High Profile, MKV: stream fail, hard decoding ok 1280x720, High Profile, MP4: stream ok, hard decoding ok 1280x7...”创建新页面 wikitext text/x-wiki == Xoom == === H264 === BubbleUPnP, MoboPlayer 864x480, High Profile, MKV: stream fail, hard decoding ok 1280x720, High Profile, MP4: stream ok, hard decoding ok 1280x720, High Profile, MKV: stream fail, hard decoding ok 1920x1080, High Profile, MKV: stream fail, hard decoding fail, soft decoding lag === XviD === 640x480, Simple Profile, AVI: stream ok, hard decoding fail, soft decoding ok == Galaxy Note == === H264 === BubbleUPnP, MoboPlayer 1280x720, High Profile, MP4: stream ok, hard decoding ok 1280x720, High Profile, MKV: stream ok, hard decoding ok 1920x1080, High Profile, MKV: stream ok, hard decoding ok === XviD === 640x480, Simple Profile, AVI: stream ok, hard decoding ok f71f10d4797f1940405c27783021857fc9584761 246 245 2012-06-21T18:33:58Z HenryHu 1 wikitext text/x-wiki == Xoom == === H264 === BubbleUPnP, MoboPlayer {| ! 分辨率 !! 配置 !! 容器 !! streaming !! 硬解 !! 软解 !! |- || 864x480 || High Profile || MKV || fail || ok || || |- || 1280x720 || High Profile || MP4 || ok || ok || |- || 1280x720 || High Profile || MKV || fail || lag || |- || 1920x1080 || High Profile || MKV || fail || fail || lag |} === XviD === {| ! 分辨率 !! 配置 !! 容器 !! streaming !! 硬解 !! 软解 !! |- || 640x480 || Simple Profile || AVI || ok || fail || ok |} == Galaxy Note == === H264 === BubbleUPnP, MoboPlayer {| ! 分辨率 !! 配置 !! 容器 !! streaming !! 硬解 !! 软解 !! |- || 1280x720 || High Profile || MP4 || ok || ok || |- || 1280x720 || High Profile || MKV || ok || ok || |- || 1920x1080 || High Profile || MKV || ok || ok || |} === XviD === {| ! 分辨率 !! 配置 !! 容器 !! streaming !! 硬解 !! 软解 !! |- || 640x480 || Simple Profile || AVI || ok || ok |} 100800fac8726353a446f43e953c7ed1b262a630 Pybbs 0 56 254 212 2012-06-30T04:49:19Z HenryHu 1 /* 数据接口实现 */ wikitext text/x-wiki 基于Python的BBS实现,提供[[BBS数据接口]]。 == 基础结构 == === C结构的存取 === ==== 初版实现 ==== 需要在对应的类定义域:_fields与_parser。 _fields: * _fields为一个list,其中每项对应一个C结构里的域。 * 每项可以是一个字符串(域名),或者是一个list。 * 如果是一个list,那第一个必须是个字符串(域名),第二个是类型,之后是类型参数。 ** 类型1: C字符串。从内存中读取之后,会自动截断到第一个\0 ** 类型2: 需要再次parse的域。目前主要用来实现数组。类型参数是再次parse的格式字符串。 *** 例如,对于一个int数组,['friends_uid', 2, '=%di' % Config.MAXFRIENDS ],会再次用后面那个格式进行parse,得到一个list。 _parser: * 定义为struct.Struct(格式字符串) * 格式字符串里,每项对应了_fields里的一个域。 * 对于普通类型,例如int,直接在对应位置写'i'就可以。 * 对于需要再次parse的类型,这里只要取出一个字符串就完了,一般是'9s'这样的形式。 == 数据接口实现 == * 登录 ** 用户名/密码登录 :: '''已实现''',考虑安全原因禁用 ** OAuth登录 :: '''部分实现''',只是能用而已…… * 帖子 ** 获取帖子 :: '''已实现''' ** 发帖 ** 同主题上一帖/下一贴 :: '''已实现''' * 版面 ** 获取所有版面列表 :: '''已实现''' * 精华区 * 收藏夹 ** 获取收藏夹列表 :: '''已实现''' * 消息 : 在XMPP接口中实现 * 好友列表 : 在XMPP接口中实现 * 邮箱 == XMPP实现 == XMPP阶段: * 认证 ** 基于外部OAuth ** 基于明文 :: TLS层已经加密了,所以无所谓。 :: '''已实现''',见xmppauth.XMPPAuth类 * 登录 ** 更新用户信息 ** 增加session :: '''已实现'''。在xmppserver.XMPPServer类中__init__部分。调用Session.Register()进行注册。 * 好友列表 ** 获取好友列表(roaster) :: '''已实现'''。在roster.Roster类中。 ** 跟踪好友状态并更新好友列表 :: '''已实现'''。在rosters.Rosters类中,包括update_sessions()等 ** 隐身功能 :: '''已实现''',看不见的人,就是看不见…… :: 但是在消息方面有个问题。原来是允许给隐身的人回复消息的,但现在不好判断是否回复,干脆统统不许。 ** 增加好友 ** 删除好友 ** 修改好友昵称 * 消息 ** 发送消息 :: '''已实现'''。参见rosters.Rosters.send_msg() ** 消息通知 :: '''已实现'''。 :: 目前设计为,当收到SIGUSR2,让所有登录用户检查是否有新消息。 ** 接收消息 :: '''已实现'''。保存内部已读索引,每次检查消息,如果有新消息,则发送给用户。 * 修改状态 * 扩展 很多成本不大…… 有空搞搞就好了 ** jabber:iq:last :: 上次活动时间(在线)/上次上线时间(下线)/uptime(服务器) ** jabber:iq:version :: 软件版本/系统信息 ** vcard-temp :: 用户信息,例如名字、全名、…… :: '''初步实现''',返回用户名…… ** urn:xmpp:time :: 用户本地时间…… ** disco#info :: 查询支持的扩展列表。'''已实现''' * 注销 ** 更新用户信息 ** 移除session :: '''已实现'''。用Session.Unregister()。 6b9a4c127db5dbd00431a916aa5a875368cd38b0 255 254 2012-07-02T16:14:03Z HenryHu 1 /* 初版实现 */ wikitext text/x-wiki 基于Python的BBS实现,提供[[BBS数据接口]]。 == 基础结构 == === C结构的存取 === ==== 初版实现 ==== 需要在对应的类定义域:_fields与_parser。 _fields: * _fields为一个list,其中每项对应一个C结构里的域。 * 每项可以是一个字符串(域名),或者是一个list。 * 如果是一个list,那第一个必须是个字符串(域名),第二个是类型,之后是类型参数。 ** 类型1: C字符串。从内存中读取之后,会自动截断到第一个\0 ** 类型2: 需要再次parse的域。目前主要用来实现数组。类型参数是再次parse的格式字符串。 *** 例如,对于一个int数组,['friends_uid', 2, '=%di' % Config.MAXFRIENDS ],会再次用后面那个格式进行parse,得到一个list。 _parser: * 定义为struct.Struct(格式字符串) * 格式字符串里,每项对应了_fields里的一个域。 * 对于普通类型,例如int,直接在对应位置写'i'就可以。 * 对于需要再次parse的类型,这里只要取出一个字符串就完了,一般是'9s'这样的形式。 样例: 来自UserInfo类 <source lang="python"> _fields = ['active', 'uid', 'pid', 'invisible', 'sockactive', 'sockaddr', 'destuid', 'mode', 'pager', 'in_chat', ['chatid', 1], ['from', 1], 'logintime', 'fill', 'freshtime', 'utmpkey', 'mailbox_prop', ['userid', 1], ['realname', 1], ['username', 1], 'friendsnum', ['friends_uid', 2, '=%di' % Config.MAXFRIENDS ], 'currentboard', 'mailcheck'] _parser = struct.Struct('=iiiiiiiiii16s%dsi36siiI20s20s40si%dsiI' % (Config.IPLEN + 4, Config.MAXFRIENDS * 4)) </source> 对应c结构: <source lang="c"> struct user_info { /* Structure used in UTMP file */ int active; /* When allocated this field is true */ int uid; /* Used to find user name in passwd file */ int pid; /* kill() to notify user of talk request */ int invisible; /* Used by cloaking function in Xyz menu */ int sockactive; /* Used to coordinate talk requests */ int sockaddr; /* ... */ int destuid; /* talk uses this to identify who called */ int mode; /* UL/DL, Talk Mode, Chat Mode, ... */ int pager; /* pager toggle, true, or false */ int in_chat; /* for in_chat commands */ char chatid[16]; /* chat id, if in chat mode */ char from[IPLEN + 4]; /* machine name the user called in from */ time_t logintime; #ifdef HAVE_WFORUM char fill[35]; unsigned char yank; #else char fill[36]; #endif time_t freshtime; int utmpkey; unsigned int mailbox_prop; /* properties of currentuser's mailbox */ char userid[20]; char realname[20]; char username[40]; int friendsnum; int friends_uid[MAXFRIENDS]; #ifdef FRIEND_MULTI_GROUP unsigned int friends_p[MAXFRIENDS]; #endif int currentboard; unsigned int mailcheck; /* if have new mail or new msg, stiger */ }; </source> == 数据接口实现 == * 登录 ** 用户名/密码登录 :: '''已实现''',考虑安全原因禁用 ** OAuth登录 :: '''部分实现''',只是能用而已…… * 帖子 ** 获取帖子 :: '''已实现''' ** 发帖 ** 同主题上一帖/下一贴 :: '''已实现''' * 版面 ** 获取所有版面列表 :: '''已实现''' * 精华区 * 收藏夹 ** 获取收藏夹列表 :: '''已实现''' * 消息 : 在XMPP接口中实现 * 好友列表 : 在XMPP接口中实现 * 邮箱 == XMPP实现 == XMPP阶段: * 认证 ** 基于外部OAuth ** 基于明文 :: TLS层已经加密了,所以无所谓。 :: '''已实现''',见xmppauth.XMPPAuth类 * 登录 ** 更新用户信息 ** 增加session :: '''已实现'''。在xmppserver.XMPPServer类中__init__部分。调用Session.Register()进行注册。 * 好友列表 ** 获取好友列表(roaster) :: '''已实现'''。在roster.Roster类中。 ** 跟踪好友状态并更新好友列表 :: '''已实现'''。在rosters.Rosters类中,包括update_sessions()等 ** 隐身功能 :: '''已实现''',看不见的人,就是看不见…… :: 但是在消息方面有个问题。原来是允许给隐身的人回复消息的,但现在不好判断是否回复,干脆统统不许。 ** 增加好友 ** 删除好友 ** 修改好友昵称 * 消息 ** 发送消息 :: '''已实现'''。参见rosters.Rosters.send_msg() ** 消息通知 :: '''已实现'''。 :: 目前设计为,当收到SIGUSR2,让所有登录用户检查是否有新消息。 ** 接收消息 :: '''已实现'''。保存内部已读索引,每次检查消息,如果有新消息,则发送给用户。 * 修改状态 * 扩展 很多成本不大…… 有空搞搞就好了 ** jabber:iq:last :: 上次活动时间(在线)/上次上线时间(下线)/uptime(服务器) ** jabber:iq:version :: 软件版本/系统信息 ** vcard-temp :: 用户信息,例如名字、全名、…… :: '''初步实现''',返回用户名…… ** urn:xmpp:time :: 用户本地时间…… ** disco#info :: 查询支持的扩展列表。'''已实现''' * 注销 ** 更新用户信息 ** 移除session :: '''已实现'''。用Session.Unregister()。 345a34bd8cda1953d93e7cbec83e94963643e573 256 255 2012-07-02T16:21:22Z HenryHu 1 /* C结构的存取 */ wikitext text/x-wiki 基于Python的BBS实现,提供[[BBS数据接口]]。 == 基础结构 == === C结构的存取 === ==== 初版实现 ==== 需要在对应的类定义域:_fields与_parser。之后利用Util.Pack()和Util.Unpack()将对象打包成一个和结构一样长的字符串,或者从一个字符串解包成整个对象。 _fields: * _fields为一个list,其中每项对应一个C结构里的域。 * 每项可以是一个字符串(域名),或者是一个list。 * 如果是一个list,那第一个必须是个字符串(域名),第二个是类型,之后是类型参数。 ** 类型1: C字符串。从内存中读取之后,会自动截断到第一个\0 ** 类型2: 需要再次parse的域。目前主要用来实现数组。类型参数是再次parse的格式字符串。 *** 例如,对于一个int数组,['friends_uid', 2, '=%di' % Config.MAXFRIENDS ],会再次用后面那个格式进行parse,得到一个list。 _parser: * 定义为struct.Struct(格式字符串) * 格式字符串里,每项对应了_fields里的一个域。 * 对于普通类型,例如int,直接在对应位置写'i'就可以。 * 对于需要再次parse的类型,这里只要取出一个字符串就完了,一般是'9s'这样的形式。 样例: 来自UserInfo类 <source lang="python"> _fields = ['active', 'uid', 'pid', 'invisible', 'sockactive', 'sockaddr', 'destuid', 'mode', 'pager', 'in_chat', ['chatid', 1], ['from', 1], 'logintime', 'fill', 'freshtime', 'utmpkey', 'mailbox_prop', ['userid', 1], ['realname', 1], ['username', 1], 'friendsnum', ['friends_uid', 2, '=%di' % Config.MAXFRIENDS ], 'currentboard', 'mailcheck'] _parser = struct.Struct('=iiiiiiiiii16s%dsi36siiI20s20s40si%dsiI' % (Config.IPLEN + 4, Config.MAXFRIENDS * 4)) </source> 对应c结构: <source lang="c"> struct user_info { /* Structure used in UTMP file */ int active; /* When allocated this field is true */ int uid; /* Used to find user name in passwd file */ int pid; /* kill() to notify user of talk request */ int invisible; /* Used by cloaking function in Xyz menu */ int sockactive; /* Used to coordinate talk requests */ int sockaddr; /* ... */ int destuid; /* talk uses this to identify who called */ int mode; /* UL/DL, Talk Mode, Chat Mode, ... */ int pager; /* pager toggle, true, or false */ int in_chat; /* for in_chat commands */ char chatid[16]; /* chat id, if in chat mode */ char from[IPLEN + 4]; /* machine name the user called in from */ time_t logintime; #ifdef HAVE_WFORUM char fill[35]; unsigned char yank; #else char fill[36]; #endif time_t freshtime; int utmpkey; unsigned int mailbox_prop; /* properties of currentuser's mailbox */ char userid[20]; char realname[20]; char username[40]; int friendsnum; int friends_uid[MAXFRIENDS]; #ifdef FRIEND_MULTI_GROUP unsigned int friends_p[MAXFRIENDS]; #endif int currentboard; unsigned int mailcheck; /* if have new mail or new msg, stiger */ }; </source> ==== 新版实现 ==== 利用python的property系统,将每个域添加为该类的一个property。 需要在类中定义_fields成员,之后在类上加上@init_fields这个decorator来自动根据_fields添加property。 _fields为一个list,其中每项也是一个list,每项的第一个元素为域名,第二个为该域的类型。之所以不用hash,是因为域是有次序的。 需要实现read()和write()接口,在读写域时会调用这俩函数。 样例: <source lang="python"> @init_fields class UserRecord(object): _fields = [ ['userid' , Str(Config.IDLEN + 2)], ['flags' , I8()], ['title' , U8()], ['firstlogin' , U32()], ['lasthost' , Str(16)], ['numlogins' , U32()], ['numposts' , U32()], ['passwd' , FixStr(Config.OLDPASSLEN)], ['padding' , FixStr(2)], ['username' , Str(Config.NAMELEN)], ['club_read_rights' , Array(I32, Config.MAXCLUB / 32)], ['club_write_rights' , Array(I32, Config.MAXCLUB / 32)], ['md5passwd' , FixStr(Config.MD5PASSLEN)], ['userlevel' , U32()], ['lastlogin' , U32()], ['stay' , U32()], ['signature' , I32()], ['userdef' , Array(I32, 2)], ['notedate' , U32()], ['noteline' , I32()], ['notemode' , I32()], ['exittime' , U32()], ['usedspace' , U32()] ] </source> 对应c结构: <source lang="c"> struct userec { /* Structure used to hold information in */ char userid[IDLEN + 2]; /* PASSFILE */ char flags; /*一些标志,戒网,版面排序之类的*/ unsigned char title; /*用户级别*/ time_t firstlogin; char lasthost[16]; unsigned int numlogins; unsigned int numposts; #ifdef CONV_PASS char passwd[OLDPASSLEN]; char unused_padding[2]; #endif char username[NAMELEN]; unsigned int club_read_rights[MAXCLUB>>5]; unsigned int club_write_rights[MAXCLUB>>5]; unsigned char md5passwd[MD5PASSLEN]; unsigned userlevel; time_t lastlogin; time_t stay; int signature; unsigned int userdefine[2]; time_t notedate; int noteline; int notemode; time_t exittime; /* 生日数据转移到 userdata 结构中 */ unsigned int usedspace; /* used space of user's mailbox, in bytes */ #ifdef HAVE_USERMONEY int money; int score; char unused[20]; #endif }; </source> == 数据接口实现 == * 登录 ** 用户名/密码登录 :: '''已实现''',考虑安全原因禁用 ** OAuth登录 :: '''部分实现''',只是能用而已…… * 帖子 ** 获取帖子 :: '''已实现''' ** 发帖 ** 同主题上一帖/下一贴 :: '''已实现''' * 版面 ** 获取所有版面列表 :: '''已实现''' * 精华区 * 收藏夹 ** 获取收藏夹列表 :: '''已实现''' * 消息 : 在XMPP接口中实现 * 好友列表 : 在XMPP接口中实现 * 邮箱 == XMPP实现 == XMPP阶段: * 认证 ** 基于外部OAuth ** 基于明文 :: TLS层已经加密了,所以无所谓。 :: '''已实现''',见xmppauth.XMPPAuth类 * 登录 ** 更新用户信息 ** 增加session :: '''已实现'''。在xmppserver.XMPPServer类中__init__部分。调用Session.Register()进行注册。 * 好友列表 ** 获取好友列表(roaster) :: '''已实现'''。在roster.Roster类中。 ** 跟踪好友状态并更新好友列表 :: '''已实现'''。在rosters.Rosters类中,包括update_sessions()等 ** 隐身功能 :: '''已实现''',看不见的人,就是看不见…… :: 但是在消息方面有个问题。原来是允许给隐身的人回复消息的,但现在不好判断是否回复,干脆统统不许。 ** 增加好友 ** 删除好友 ** 修改好友昵称 * 消息 ** 发送消息 :: '''已实现'''。参见rosters.Rosters.send_msg() ** 消息通知 :: '''已实现'''。 :: 目前设计为,当收到SIGUSR2,让所有登录用户检查是否有新消息。 ** 接收消息 :: '''已实现'''。保存内部已读索引,每次检查消息,如果有新消息,则发送给用户。 * 修改状态 * 扩展 很多成本不大…… 有空搞搞就好了 ** jabber:iq:last :: 上次活动时间(在线)/上次上线时间(下线)/uptime(服务器) ** jabber:iq:version :: 软件版本/系统信息 ** vcard-temp :: 用户信息,例如名字、全名、…… :: '''初步实现''',返回用户名…… ** urn:xmpp:time :: 用户本地时间…… ** disco#info :: 查询支持的扩展列表。'''已实现''' * 注销 ** 更新用户信息 ** 移除session :: '''已实现'''。用Session.Unregister()。 1554765dd943debde3bc025270037aa6d5f6bcf5 BBS 精华区 0 88 257 2012-07-05T20:19:21Z HenryHu 1 以内容“== 权限系统 == === 载入时 === 参见'''a_loadnames''' 1.0 有PERM_SYSOP则一切可见。否则: * 1.1 BM: SYSOPS: 需要PERM_SYSOP可见 * 1.2 BM: BMS: 需...”创建新页面 wikitext text/x-wiki == 权限系统 == === 载入时 === 参见'''a_loadnames''' 1.0 有PERM_SYSOP则一切可见。否则: * 1.1 BM: SYSOPS: 需要PERM_SYSOP可见 * 1.2 BM: BMS: 需要PERM_BOARDS可见 * 1.3 BM: ZIXIAs: 需要PERM_SECANC可见(……) === 显示时 === 参见'''a_menu''' 上层传入参数:是否''有权限'',是否''需要权限'',本层只会在此基础上增加。也就是说,一旦''有权限''则在下层都有;一旦''需要权限''则下层都需要。 2.0 如果本层标题内有BM:,则 * 2.1 如果用户有PERM_BOARDS且出现在本层标题内,或者用户是SYSOP,则''有权限'' * 2.2 否则如果''需要权限''并且''没权限'',则返回(退出本层) 3 接下来:如果本层标题有BM: BMS或者BM: SECRET或者BM: SYSOPS,则''需要权限''。 注意,设置''需要权限''要在下一层才生效…… === 效果 === 综上,可以对不同的目录的效果进行分析: * BM: SYSOPS: 根据1.1,只有PERM_SYSOP的人可见。反正都是SYSOP了,啥都可以 * BM: BMS: 根据1.2,只有PERM_BOARDS可见。 ** 但如果这人在一路上都没有拿到权限,那么 *** 如果上层需要权限,根据2.0以及2.2,他进不去。 *** 如果路上都不需要权限,他可以进去。之后根据2.0和2.1,对于有他名字的BM:,他可以进去并获得权限。对其他BM:,根据2.0和2.2,他进不去。对其他项目他可以进去。 ** 如果他路上拿到权限了,那么根据2.0以及2.2,他可以进去。根据3,从本层开始,接下来都需要权限。 * BM: ZIXIAs: 根据1.3,只有PERM_SECANC可见,可见的都能进去。 * BM: SECRET: 谁都可见。 ** 如果他一路上都没有拿到权限,那么 *** 如果上层需要权限,那根据2.0和2.2,他进不去。 *** 如果上层不需要,他可以进去,还是没权限,之后都要权限。根据2.0-2.2,他可以进去没有BM:的目录。对于有BM:的,如果他有PERM_BOARDS并且有名字出现,那么可以进去并获得权限,否则进不去。 ** 如果他有权限了,那就都可以进了。 * BM: 其他: 谁都可见。 ** 如果他都没拿到权限,那么 *** 如果已经需要权限,那他进不去。 *** 如果不需要权限,他可以进去。如果他名字出现了,他能够拿到权限。 ** 如果他有权限了,那随意。 d79d78da492bb17f8ea7955ecdee369926356334 258 257 2012-07-05T20:23:11Z HenryHu 1 /* 效果 */ wikitext text/x-wiki == 权限系统 == === 载入时 === 参见'''a_loadnames''' 1.0 有PERM_SYSOP则一切可见。否则: * 1.1 BM: SYSOPS: 需要PERM_SYSOP可见 * 1.2 BM: BMS: 需要PERM_BOARDS可见 * 1.3 BM: ZIXIAs: 需要PERM_SECANC可见(……) === 显示时 === 参见'''a_menu''' 上层传入参数:是否''有权限'',是否''需要权限'',本层只会在此基础上增加。也就是说,一旦''有权限''则在下层都有;一旦''需要权限''则下层都需要。 2.0 如果本层标题内有BM:,则 * 2.1 如果用户有PERM_BOARDS且出现在本层标题内,或者用户是SYSOP,则''有权限'' * 2.2 否则如果''需要权限''并且''没权限'',则返回(退出本层) 3 接下来:如果本层标题有BM: BMS或者BM: SECRET或者BM: SYSOPS,则''需要权限''。 注意,设置''需要权限''要在下一层才生效…… === 效果 === 综上,可以对不同的目录的效果进行分析: * BM: SYSOPS: 根据1.1,只有PERM_SYSOP的人可见。反正都是SYSOP了,啥都可以 * BM: BMS: 根据1.2,只有PERM_BOARDS可见。 ** 但如果这人在一路上都没有拿到权限,那么 *** 如果上层需要权限,根据2.0以及2.2,他进不去。 *** 如果路上都不需要权限,他可以进去。之后根据2.0和2.1,对于有他名字的BM:,他可以进去并获得权限。对其他BM:,根据2.0和2.2,他进不去。对其他项目他可以进去。 ** 如果他路上拿到权限了,那么根据2.0以及2.2,他可以进去。根据3,从本层开始,接下来都需要权限。 * BM: ZIXIAs: 根据1.3,只有PERM_SECANC可见。 ** 如果他没权限,那么 *** 如果需要权限,他进不去。 *** 如果不需要权限,他能进去。 ** 如果他有权限了,那随意。 * BM: SECRET: 谁都可见。 ** 如果他一路上都没有拿到权限,那么 *** 如果上层需要权限,那根据2.0和2.2,他进不去。 *** 如果上层不需要,他可以进去,还是没权限,之后都要权限。根据2.0-2.2,他可以进去没有BM:的目录。对于有BM:的,如果他有PERM_BOARDS并且有名字出现,那么可以进去并获得权限,否则进不去。 ** 如果他有权限了,那就都可以进了。 * BM: 其他: 谁都可见。 ** 如果他都没拿到权限,那么 *** 如果已经需要权限,那他进不去。 *** 如果不需要权限,他可以进去。如果他名字出现了,他能够拿到权限。 ** 如果他有权限了,那随意。 fa15c6d2c95d4d64032ab5688dbf13102e620e5f BBS数据接口 0 76 266 265 2012-07-06T20:47:01Z HenryHu 1 /* 列出收藏夹 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>} } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。 == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID> } </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "title": <string: Post title>, "content": <string: Post content>, "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, 'content': <string: content of the post>, 'picattach': [ <AttachmentInfo: information of one attachment>, ... ], 'otherattach': [ <AttachmentInfo: information of one attachment>, ... ] } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> ccec5a74f0e4b20281baab755ae92b1f6791fec9 267 266 2012-07-06T20:48:21Z HenryHu 1 /* 列出收藏夹 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>} } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。 == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID> } </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "title": <string: Post title>, "content": <string: Post content>, "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, 'content': <string: content of the post>, 'picattach': [ <AttachmentInfo: information of one attachment>, ... ], 'otherattach': [ <AttachmentInfo: information of one attachment>, ... ] } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> c261d805dab62a8ec7a8b5a69901eb7b62f2c53e 268 267 2012-07-07T01:24:18Z HenryHu 1 /* 清除未读标记 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>} } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。 === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID> } </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "title": <string: Post title>, "content": <string: Post content>, "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, 'content': <string: content of the post>, 'picattach': [ <AttachmentInfo: information of one attachment>, ... ], 'otherattach': [ <AttachmentInfo: information of one attachment>, ... ] } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> fc012d1030b901026679560f7d283a63bed5635a 269 268 2012-07-08T03:58:11Z HenryHu 1 /* 获取用户信息 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>} } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。 === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID> } </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "title": <string: Post title>, "content": <string: Post content>, "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, 'content': <string: content of the post>, 'picattach': [ <AttachmentInfo: information of one attachment>, ... ], 'otherattach': [ <AttachmentInfo: information of one attachment>, ... ] } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> 5fdbb40cf22ad4bf45bbc65e4fa9bd35cc441151 270 269 2012-07-09T18:50:20Z HenryHu 1 /* 获取帖子 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>} } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。 === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID> } </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, "title": <string: Post title>, "content": <string: Post content>, "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, 'content': <string: content of the post>, 'picattach': [ <AttachmentInfo: information of one attachment>, ... ], 'otherattach': [ <AttachmentInfo: information of one attachment>, ... ] } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> f98767d46112cc52e8d25415f8674d30728c7969 277 270 2012-08-09T01:02:23Z HenryHu 1 /* 发帖/回帖 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>} } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。 === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID> } </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, "title": <string: Post title>, "content": <string: Post content>, "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, 'content': <string: content of the post>, 'picattach': [ <AttachmentInfo: information of one attachment>, ... ], 'otherattach': [ <AttachmentInfo: information of one attachment>, ... ] } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> 4537e04a1833613e8c8852f52362717595849c28 278 277 2012-08-09T01:03:55Z HenryHu 1 /* 帖子 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>} } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。 === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID> } </source> PostAttachInfo: <source lang="javascript"> { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> } </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, "title": <string: Post title>, "content": <string: Post content>, "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, 'content': <string: content of the post>, 'picattach': [ <AttachmentInfo: information of one attachment>, ... ], 'otherattach': [ <AttachmentInfo: information of one attachment>, ... ] } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> 91968651ab4efee0da215d15b769ad0292c80009 279 278 2012-08-09T01:04:50Z HenryHu 1 /* 帖子 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>} } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。 === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID> } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, "title": <string: Post title>, "content": <string: Post content>, "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, 'content': <string: content of the post>, 'picattach': [ <AttachmentInfo: information of one attachment>, ... ], 'otherattach': [ <AttachmentInfo: information of one attachment>, ... ] } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> c3305a8bd93db1de218b3155eeb95893b4ad8e62 280 279 2012-08-09T01:08:24Z HenryHu 1 /* 获取默认签名档编号 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>} } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。 === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID> } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, "title": <string: Post title>, "content": <string: Post content>, "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, 'content': <string: content of the post>, 'picattach': [ <AttachmentInfo: information of one attachment>, ... ], 'otherattach': [ <AttachmentInfo: information of one attachment>, ... ] } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> 994586c87ee238f90d765599f318425ea95b7185 283 280 2012-08-13T20:30:46Z HenryHu 1 /* 清除未读标记 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>} } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。 === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID> } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, "title": <string: Post title>, "content": <string: Post content>, "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, 'content': <string: content of the post>, 'picattach': [ <AttachmentInfo: information of one attachment>, ... ], 'otherattach': [ <AttachmentInfo: information of one attachment>, ... ] } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> a9469907abea91f85663b78c9420544c78ef35d0 284 283 2012-08-13T20:31:30Z HenryHu 1 /* 清除未读标记 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>} } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID> } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, "title": <string: Post title>, "content": <string: Post content>, "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, 'content': <string: content of the post>, 'picattach': [ <AttachmentInfo: information of one attachment>, ... ], 'otherattach': [ <AttachmentInfo: information of one attachment>, ... ] } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> 784ade40842352ff20f4cc983a2a95c812187e1d 285 284 2012-08-16T19:06:28Z HenryHu 1 /* 上传文件 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>} } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID> } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, "title": <string: Post title>, "content": <string: Post content>, "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, 'content': <string: content of the post>, 'picattach': [ <AttachmentInfo: information of one attachment>, ... ], 'otherattach': [ <AttachmentInfo: information of one attachment>, ... ] } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> a41264277298189ceeccd2f8a375fb93f13f42aa 286 285 2012-08-16T19:09:03Z HenryHu 1 /* 帖子 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>} } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, "title": <string: Post title>, "content": <string: Post content>, "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, 'content': <string: content of the post>, 'picattach': [ <AttachmentInfo: information of one attachment>, ... ], 'otherattach': [ <AttachmentInfo: information of one attachment>, ... ] } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> 3b1ba4181d7c6edf9278ff2e5f4495b4e299f380 287 286 2012-08-16T19:09:34Z HenryHu 1 /* 邮箱 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>} } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, "title": <string: Post title>, "content": <string: Post content>, "owner": <string: Poster>, "id": <int: Post ID>, "xid": <int: unique post ID> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, 'content': <string: content of the post>, 'picattach': [ <AttachmentInfo: information of one attachment>, ... ], 'otherattach': [ <AttachmentInfo: information of one attachment>, ... ] } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> 86a43c7dabd19348621281ba6a0c36e1cdd127b8 288 287 2012-08-16T19:15:18Z HenryHu 1 /* 帖子 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>} } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, 'content': <string: content of the post>, 'picattach': [ <AttachmentInfo: information of one attachment>, ... ], 'otherattach': [ <AttachmentInfo: information of one attachment>, ... ] } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> 224266c33f986bd623b9b32a5d6958de01e8ef80 289 288 2012-08-16T19:16:27Z HenryHu 1 /* 获取帖子 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>} } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, <*PostContent: content of the post> } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> b9da103dce8300d927fbea5f6bdd71ff293d3f6a 290 289 2012-08-16T19:17:46Z HenryHu 1 /* 获取帖子 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <int: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>} } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, <*PostContent: content of the post>, 'attachlink': <string: URL of the page showing attachments. add '&a=offset' for individual attachment> } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> 5f2bb283e5ff5659cbc62d5886f396b425944b40 301 290 2012-09-13T22:13:35Z HenryHu 1 /* 版面 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <string: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>} } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, <*PostContent: content of the post>, 'attachlink': <string: URL of the page showing attachments. add '&a=offset' for individual attachment> } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> d04642baa11e83b218f7c2bf7dab876e1f6873dd 312 301 2013-01-14T00:09:33Z HenryHu 1 /* 版面 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <string: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>}, "group": <int: Group ID, or 0 if not in a group, match with id">, "isdir": <boolean: is a board group> [optional], "child_count": <int: children count of the board group> [optional] } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |- | group || int || Board group to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, <*PostContent: content of the post>, 'attachlink': <string: URL of the page showing attachments. add '&a=offset' for individual attachment> } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> 42e9f21947d66cc10b113b494ea52412e4afa303 313 312 2013-01-14T00:12:43Z HenryHu 1 /* 版面 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <string: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>}, "group": <int: Group ID, or 0 if not in a group, match with id>, "isdir": <boolean: is a board group> [optional], "child_count": <int: children count of the board group> [optional] } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |- | group || int || Board group to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, <*PostContent: content of the post>, 'attachlink': <string: URL of the page showing attachments. add '&a=offset' for individual attachment> } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> 4bd7b45d2742a5f68f1e66c1a5c40e52fc45f1a3 APK (de)compile 0 89 271 2012-07-12T21:37:50Z HenryHu 1 以内容“APK 编译/反编译的工具包 [[文件:apk_jar.png]]”创建新页面 wikitext text/x-wiki APK 编译/反编译的工具包 [[文件:apk_jar.png]] b583d7265352626acf245ed5cb54d026b154b383 273 271 2012-07-12T21:50:53Z HenryHu 1 wikitext text/x-wiki APK 编译/反编译的工具包 [[文件:apk_jar.png]] == 工具 == * dex2jar: [http://dex2jar.googlecode.com dex2jar] 据说是国人开发的,主要能够在Dalvik VM bytecode和JVM bytecode之间互转 * apktool: [http://apktool.googlecode.com apktool] 可以在apk和Dalvik VM汇编之间互转 * signapk: android SDK 自带,签名工具 * ded: [http://siis.cse.psu.edu/ded/ ded] 将APK解包,转换成JVM bytecode,再反汇编 * kimera: [http://www.cs.cornell.edu/people/egs/kimera/disassembler.html kimera] JVM bytecode反汇编器 * soot: [http://www.sable.mcgill.ca/soot/ Soot] JVM bytecode优化器/反编译器 * jasmin: [http://jasmin.sourceforge.net jasmin] 开源jvm汇编器 * jdgui: [http://java.decompiler.free.fr/ JD] JVM bytecode反编译器 * javac, zip, unzip: 我就不说什么了…… * dx: android SDK 自带,转换JVM bytecode为Dalvik VM bytecode * smali/baksmali: [http://smali.googlecode.com smali] Dalvik VM 汇编器/反汇编器 == 修改APK == === 可选路线1 === APK -> [apktool] -> 一堆.smali文件和资源 -> [修改] -> 修改结果 -> [apktool] -> 修改APK -> [signapk] -> 签名了的APK === 可选路线2 === APK -> [dex2jar] -> JAR -> [dex2jar] -> 一堆.jasmin -> [修改] -> 修改结果 -> [dex2jar] -> DEX -> [zip] -> 修改APK -> [dex2jar] -> 签名了的APK 678da21756e925200cf2a8e956e8c0a930566d83 274 273 2012-07-12T21:51:58Z HenryHu 1 /* 工具 */ wikitext text/x-wiki APK 编译/反编译的工具包 [[文件:apk_jar.png]] == 工具 == * [http://dex2jar.googlecode.com dex2jar] 据说是国人开发的,主要能够在Dalvik VM bytecode和JVM bytecode之间互转 * [http://apktool.googlecode.com apktool] 可以在apk和Dalvik VM汇编之间互转 * signapk: android SDK 自带,签名工具 * [http://siis.cse.psu.edu/ded/ ded] 将APK解包,转换成JVM bytecode,再反汇编 * [http://www.cs.cornell.edu/people/egs/kimera/disassembler.html kimera] JVM bytecode反汇编器 * [http://www.sable.mcgill.ca/soot/ soot] JVM bytecode优化器/反编译器 * [http://jasmin.sourceforge.net jasmin] 开源jvm汇编器 * [http://java.decompiler.free.fr/ jdgui] JVM bytecode反编译器 * javac, zip, unzip: 我就不说什么了…… * dx: android SDK 自带,转换JVM bytecode为Dalvik VM bytecode * [http://smali.googlecode.com smali/baksmali] Dalvik VM 汇编器/反汇编器 == 修改APK == === 可选路线1 === APK -> [apktool] -> 一堆.smali文件和资源 -> [修改] -> 修改结果 -> [apktool] -> 修改APK -> [signapk] -> 签名了的APK === 可选路线2 === APK -> [dex2jar] -> JAR -> [dex2jar] -> 一堆.jasmin -> [修改] -> 修改结果 -> [dex2jar] -> DEX -> [zip] -> 修改APK -> [dex2jar] -> 签名了的APK f568962c9b9b72ab78c875f5579b6c13dd37400d 275 274 2012-07-13T17:15:24Z HenryHu 1 /* 工具 */ wikitext text/x-wiki APK 编译/反编译的工具包 [[文件:apk_jar.png]] == 工具 == * [http://dex2jar.googlecode.com dex2jar] 据说是国人开发的,主要能够在Dalvik VM bytecode和JVM bytecode之间互转 * [http://android-apktool.googlecode.com apktool] 可以在apk和Dalvik VM汇编之间互转 * signapk: android SDK 自带,签名工具 * [http://siis.cse.psu.edu/ded/ ded] 将APK解包,转换成JVM bytecode,再反汇编 * [http://www.cs.cornell.edu/people/egs/kimera/disassembler.html kimera] JVM bytecode反汇编器 * [http://www.sable.mcgill.ca/soot/ soot] JVM bytecode优化器/反编译器 * [http://jasmin.sourceforge.net jasmin] 开源jvm汇编器 * [http://java.decompiler.free.fr/ jdgui] JVM bytecode反编译器 * javac, zip, unzip: 我就不说什么了…… * dx: android SDK 自带,转换JVM bytecode为Dalvik VM bytecode * [http://smali.googlecode.com smali/baksmali] Dalvik VM 汇编器/反汇编器 == 修改APK == === 可选路线1 === APK -> [apktool] -> 一堆.smali文件和资源 -> [修改] -> 修改结果 -> [apktool] -> 修改APK -> [signapk] -> 签名了的APK === 可选路线2 === APK -> [dex2jar] -> JAR -> [dex2jar] -> 一堆.jasmin -> [修改] -> 修改结果 -> [dex2jar] -> DEX -> [zip] -> 修改APK -> [dex2jar] -> 签名了的APK 67ae5ece1cce117fb16b8867629b3b347316c338 文件:Apk jar.png 6 90 272 2012-07-12T21:38:18Z HenryHu 1 relations between APK and JAR and other files wikitext text/x-wiki relations between APK and JAR and other files 0aaa72c22232d402e432791e1acb55d2d95bbba2 AndWell 0 85 276 232 2012-08-07T19:27:28Z HenryHu 1 /* Change Log */ wikitext text/x-wiki === Change Log === 0.2.11 * workaround android 4.1 TextView bug (#35466) 0.2.10 * fix lists in filtered mode * get OAuth code automatically 0.2.9 * Bug fix: release connection for reuse 0.2.8 * Thread first 0.2.7 * Fix unread mark 0.2.6 * Limit timeout 0.2.5 * Various bug fix * Enhancement: Only refresh post list if necessary 0.2.4 * Enhancement: Persist connection 0.2.3 * Enhancement: Reply in view mode * Enhancement: Icons * Enhancement: Insert banner 0.2.2 * Bug fix: Stale busy dialog 0.2.1 * Enhancement: Show busy dialog when posting / replying * Enhancement: Save last qmd# 0.2 * New feature: Post * New feature: Reply 0.1.8 * Minor fix to support Google TV 0.1.7 * Minor modification to UI 0.1.6 * Initial release on the market * Require users to enter server's API address. cd2835556cef2a10f5ae19e63c98c2952b34de28 304 276 2012-12-06T01:29:17Z HenryHu 1 /* Change Log */ wikitext text/x-wiki === Change Log === 0.3.0 * Dual pane mode on large devices * Signature selection & randomization * Target new SDK (android 4.2, r17) * Chinese translation * Introduce Fragment for components 0.2.11 * workaround android 4.1 TextView bug (#35466) 0.2.10 * fix lists in filtered mode * get OAuth code automatically 0.2.9 * Bug fix: release connection for reuse 0.2.8 * Thread first 0.2.7 * Fix unread mark 0.2.6 * Limit timeout 0.2.5 * Various bug fix * Enhancement: Only refresh post list if necessary 0.2.4 * Enhancement: Persist connection 0.2.3 * Enhancement: Reply in view mode * Enhancement: Icons * Enhancement: Insert banner 0.2.2 * Bug fix: Stale busy dialog 0.2.1 * Enhancement: Show busy dialog when posting / replying * Enhancement: Save last qmd# 0.2 * New feature: Post * New feature: Reply 0.1.8 * Minor fix to support Google TV 0.1.7 * Minor modification to UI 0.1.6 * Initial release on the market * Require users to enter server's API address. bc01f663dbc494735181137e757182f5725e4180 305 304 2012-12-10T01:22:09Z HenryHu 1 /* Change Log */ wikitext text/x-wiki === Change Log === 0.3.2 * workaround a bug in Android 4.1-4.1.2 (#38770) 0.3.1 * bug fix 0.3.0 * Dual pane mode on large devices * Signature selection & randomization * Target new SDK (android 4.2, r17) * Chinese translation * Introduce Fragment for components 0.2.11 * workaround android 4.1 TextView bug (#35466) 0.2.10 * fix lists in filtered mode * get OAuth code automatically 0.2.9 * Bug fix: release connection for reuse 0.2.8 * Thread first 0.2.7 * Fix unread mark 0.2.6 * Limit timeout 0.2.5 * Various bug fix * Enhancement: Only refresh post list if necessary 0.2.4 * Enhancement: Persist connection 0.2.3 * Enhancement: Reply in view mode * Enhancement: Icons * Enhancement: Insert banner 0.2.2 * Bug fix: Stale busy dialog 0.2.1 * Enhancement: Show busy dialog when posting / replying * Enhancement: Save last qmd# 0.2 * New feature: Post * New feature: Reply 0.1.8 * Minor fix to support Google TV 0.1.7 * Minor modification to UI 0.1.6 * Initial release on the market * Require users to enter server's API address. f70cea6aab21c62f0b343b6f3e51c0a5de432f4c Reservation 0 91 281 2012-08-13T18:29:58Z HenryHu 1 以内容“Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || ? || Xuetian Weng || Before he fin...”创建新页面 wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || ? || Xuetian Weng || Before he finds his home... |- || 2012-08-26 || 2012-08-27 || Yue Liu || ? |- || 2012-08-27 || 2012-08-28 || Hao Wu & his GF || ? |- || 2012-09-01 || ? || Xin He || ? |} 1fb685f2212d2a2c437e3a821082eadd658b0844 282 281 2012-08-13T18:34:46Z HenryHu 1 wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || ? || Xuetian Weng || Before he finds his home... |- || 2012-08-26 || 2012-08-27 || Yue Liu || ? |- || 2012-08-27 || 2012-08-28 || Hao Wu & his GF || ? |- || 2012-09-01 || ? || Xin He || ? |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend dee37840cf4ce6f08d727d48ed39c811de5e6a82 291 282 2012-08-23T03:20:11Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-26 || 2012-08-27 || Yue Liu || ? |- || 2012-08-27 || 2012-08-28 || Hao Wu & his GF || ? |- || 2012-09-01 || ? || Xin He || ? |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend 457ea2dd422fc3213b9542bd335740970b27dde4 292 291 2012-08-23T03:20:31Z HenryHu 1 /* History */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-26 || 2012-08-27 || Yue Liu || ? |- || 2012-08-27 || 2012-08-28 || Hao Wu & his GF || ? |- || 2012-09-01 || ? || Xin He || ? |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng 7068376f46ed969b75e5046635314ee45bd89c37 293 292 2012-08-23T15:35:06Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... || 2012-08-26 || 2012-08-27 || Yue Liu || ? |- || 2012-08-27 || 2012-08-28 || Hao Wu & his GF || ? |- || 2012-09-01 || ? || Xin He || ? |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng bf95e2674fb42f6e0521d16696d2257ca07b9aaf 294 293 2012-08-23T15:35:15Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || 2012-08-27 || Yue Liu || ? |- || 2012-08-27 || 2012-08-28 || Hao Wu & his GF || ? |- || 2012-09-01 || ? || Xin He || ? |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng a0cbc96c552999bab584addf8471c739b5285049 295 294 2012-08-23T16:06:48Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || 2012-08-27 || Yue Liu || Before he finds home... |- || 2012-08-27 || 2012-08-28 || Hao Wu & his GF || ? |- || 2012-09-01 || ? || Xin He || ? |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng 842f0ae6764c0d51913b2b61d1222ebad7c423e7 296 295 2012-08-26T02:49:59Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || 2012-08-27 || Yue Liu || Before he finds home... |- || 2012-08-27 || 2012-08-28 || Hao Wu & his GF || ? |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-09-01 || ? || Xin He || ? |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng 6b3146507b85a65c501793a813eee336ddfdb35e 297 296 2012-08-26T03:03:01Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || 2012-08-27 || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-09-01 || ? || Xin He || ? |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng 2ae649c4d8fd7bdd78e2fc096539f49dac4f8aad 298 297 2012-08-26T03:08:50Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || ? || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-09-01 || ? || Xin He || ? |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng 655f85759ba85072b61a716707fddbf9955c1c6e 299 298 2012-09-03T00:06:39Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng ad889824ebcce36720b8736d133d72d6ae2d195b 310 299 2012-12-25T05:15:17Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-30 || Yucheng Zhang || Tour |- || 2013-01-03 || 2013-01-04 || Kaicheng Zhang || ? |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng c75cb2d7e8585d71c3ca9db8431f5e6ccdc5d459 311 310 2012-12-31T04:32:25Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng 75f37b664b50ded06cdc84e00a0bdc898a800998 BBS OAuth 0 77 300 187 2012-09-13T17:34:53Z HenryHu 1 /* 显示验证页面 */ wikitext text/x-wiki == 登录 == === 显示验证页面 === : '''GET''' /auth/auth {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | redirect_uri || string || Redirection URI || No || displaycode |- | response_type || string || Preferred response type || No || code |- | client_id || string || Client ID of the client application || No |} === 获取Token === : '''GET''' /auth/token {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | code || string || Authorization code || No |- | redirect_uri || string || Redirection URI, should match with previous requests || No |- | grant_type || string || Type of object to exchange token with || No || authorization_code |- | client_id || string || Client ID of the client application || No |- | client_secret || string || Client secret of the client application || No |} * Return value ** Success: {"access_token": <string: Token>, "token_type": <string: Token type>} ** Failure: various HTTP error code d347d99119a47d97adbd3b0744c60c0beb2f59c6 302 300 2012-09-13T22:31:47Z HenryHu 1 /* 获取Token */ wikitext text/x-wiki == 登录 == === 显示验证页面 === : '''GET''' /auth/auth {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | redirect_uri || string || Redirection URI || No || displaycode |- | response_type || string || Preferred response type || No || code |- | client_id || string || Client ID of the client application || No |} === 获取Token === : '''GET/POST''' /auth/token {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | code || string || Authorization code || No |- | redirect_uri || string || Redirection URI, should match with previous requests || No |- | grant_type || string || Type of object to exchange token with || No || authorization_code |- | client_id || string || Client ID of the client application || No |- | client_secret || string || Client secret of the client application || No |} * Return value ** Success: {"access_token": <string: Token>, "token_type": <string: Token type>} ** Failure: various HTTP error code c7f5b57734bb104d895440b249478cbd4e711e0e 314 302 2013-01-19T09:33:22Z HenryHu 1 /* 登录 */ wikitext text/x-wiki == 登录 == === 显示验证页面 === : '''GET''' /auth/auth {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | redirect_uri || string || Redirection URI || No || displaycode |- | response_type || string || Preferred response type || No || code/token |- | client_id || string || Client ID of the client application || No |} === 获取Token === : '''GET/POST''' /auth/token {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | redirect_uri || string || Redirection URI, should match with previous requests || No |- | grant_type || string || Type of object to exchange token with || No || authorization_code/refresh_token |- | code || string || Authorization code, required for grant_type = authorization_code || Yes || |- | refresh_token || string || Refresh token, required for grant_type = refresh_token || Yes || |- | client_id || string || Client ID of the client application || No || |- | client_secret || string || Client secret of the client application || No || |} * Return value ** Success: {"access_token": <string: Token>, "token_type": <string: Token type>, ["refresh_token": <string: Refresh Token>,] "expires_in": <int: Seconds before expire> } ** Failure: various HTTP error code 573999cbba770e60396b3b879013b0984793046e 315 314 2013-01-19T09:51:09Z HenryHu 1 wikitext text/x-wiki == 应用注册 == 先到/res/clients.html注册应用。 利用BBS账户登录之后,点击Register new client,填写各项信息。 * client_id: 应用标识 * client_secret: 用于验证应用(RFC6749 $2.3.1) * redirect uri: OAuth的重定向路径(RFC6749 $3.1.2) * name: 应用名字 * description: 应用说明 * logo: 图标 * website: 网站 * type: 能保证应用自身安全性的选confidential,一般选public(RFC6749 $2.1) * response type: (RFC6749 $3.1.1) ** 希望用authentication code模式的选code(RFC6749 $4.1) ** 希望用直接跳转给token模式的选token(RFC6749 $4.2) * grant type: ** 希望用authentication code模式的选authentication code(RFC6749 $4.1) ** 希望用密码登录的选password(RFC6749 $4.3, 目前禁止) ** 希望直接靠应用确认身份的选client credentials(RFC6749 $4.4, 目前禁止) ** 希望获取和使用refresh token的选refresh token(RFC6749 $6) 注册完成之后就可以作为这个应用登录了。也可以在此页面修改/删除应用信息。 == 登录 == === 显示验证页面 === : '''GET''' /auth/auth {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | redirect_uri || string || Redirection URI || No || displaycode |- | response_type || string || Preferred response type || No || code/token |- | client_id || string || Client ID of the client application || No || |- | state || string || Client state string || Yes || |} * 如果选token模式,会直接在登录成功之后重定向到$redirect_uri?access_token=<string: token>&token_type=<string: token type>&expires_in=<int: time before token expires>[&state=<string: client state>] * 如果选code模式,会跳转到$redirect_uri?code=<string: authorization code>[&state=<string: client state>],需要再进行下一步获取token。 === 获取Token === : '''GET/POST''' /auth/token {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | redirect_uri || string || Redirection URI, should match with previous requests || No |- | grant_type || string || Type of object to exchange token with || No || authorization_code/refresh_token |- | code || string || Authorization code, required for grant_type = authorization_code || Yes || |- | refresh_token || string || Refresh token, required for grant_type = refresh_token || Yes || |- | client_id || string || Client ID of the client application || No || |- | client_secret || string || Client secret of the client application || No || |} * Return value ** Success: {"access_token": <string: Token>, "token_type": <string: Token type>, ["refresh_token": <string: Refresh Token>,] "expires_in": <int: Seconds before expire> } ** Failure: various HTTP error code * refresh_token may be used to exchange for a new access_token and a new refresh_token, it will be disabled after the exchange * refresh_token可换取新access_token和refresh_token,换取后原refresh_token失效 0b128480713a52734e07dd0bab9a4d0ce3dbdfcf Android PDF Reader 0 92 303 2012-11-28T04:18:24Z HenryHu 1 以内容“{| class="wikitable" ! Application !! White-border removal !! Continuous scroll !! One-column mode !! Price !! Comment |- || ezPDF || {{No}} || {{No}} || {{Yes}} || Not...”创建新页面 wikitext text/x-wiki {| class="wikitable" ! Application !! White-border removal !! Continuous scroll !! One-column mode !! Price !! Comment |- || ezPDF || {{No}} || {{No}} || {{Yes}} || Not Free || Used for a long time |- || Mantano Lite || {{Yes}} || {{Yes}} || {{Yes}} || Free || Meets all the requirements |- || Aldiko || {{No}} || {{No}} || {{No}} || Free || Not ready for PDF |- || Perfect Viewer || {{Yes}} || {{No}} || {{No}} || Free || In fact, this is an image viewer |- || Moon+ Reader Pro || ? || ? || ? || $4.99 || I use free version for txt reading |} 4b786c13b8874d4718b010a2f7c27339a2e40838 AndWell:Settings 100 93 306 2012-12-11T17:13:39Z HenryHu 1 以内容“== Read Post == * CheckBox: Gesture * EditText(numeric:decimal): Min Start Dist * EditText(numeric:decimal): Min Start Speed * EditText(numeric:decimal): Min Start X/Y ...”创建新页面 wikitext text/x-wiki == Read Post == * CheckBox: Gesture * EditText(numeric:decimal): Min Start Dist * EditText(numeric:decimal): Min Start Speed * EditText(numeric:decimal): Min Start X/Y Ratio == Network == * EditText(numeric:unsigned): Connect Timeout (s) * EditText(numeric:unsigned): Read Timeout (s) == Post List == * EditText(numeric:unsigned): Number of posts loaded initially * EditText(numeric:unsigned): Number of posts loaded when more posts are required * CheckBox: Highlight current post * List: Use dual pane (Yes/No/Auto) == Board List == * List: Use dual pane (Yes/No/Auto) c1b8111cc4d7489b98fb5732bb2437ce2cd91d35 307 306 2012-12-11T17:15:25Z HenryHu 1 /* Network */ wikitext text/x-wiki == Read Post == * CheckBox: Gesture * EditText(numeric:decimal): Min Start Dist * EditText(numeric:decimal): Min Start Speed * EditText(numeric:decimal): Min Start X/Y Ratio == Network == * EditText(numeric:unsigned): Connect Timeout (s) * EditText(numeric:unsigned): Read Timeout (s) * CheckBox: Auto retry * EditText(numeric:unsigned): Timeout before auto retry (s) == Post List == * EditText(numeric:unsigned): Number of posts loaded initially * EditText(numeric:unsigned): Number of posts loaded when more posts are required * CheckBox: Highlight current post * List: Use dual pane (Yes/No/Auto) == Board List == * List: Use dual pane (Yes/No/Auto) 54ccdacb0badd29683c60c058dd376f423f18a02 Portability 0 94 308 2012-12-24T00:58:01Z HenryHu 1 以内容“Various portability issues, mainly between linux/freebsd * prctl() / prctl.h No prctl() in freebsd. ** To set process title, use setproctitle() ** For PR_SET_PTRACE...”创建新页面 wikitext text/x-wiki Various portability issues, mainly between linux/freebsd * prctl() / prctl.h No prctl() in freebsd. ** To set process title, use setproctitle() ** For PR_SET_PTRACER, I'm not sure now. * malloc.h Including malloc.h in freebsd leads to compile error. Use stdlib.h instead. Anyway, in linux's malloc(3) manpage, it is said that you should include stdlib.h. * libdl In linux, dlopen()/dlclose()/dlsym() are in libdl. In freebsd, they are in libc. So there is no point to link with libdl, and there is no libdl, anyway. * program_invocation_short_name No such thing in bsd. Maybe you should use argv[0]. * Include path / Lib path freebsd installs all non-base softwares into /usr/local. So, the third party include files are in /usr/local/include, and third party lib files are in /usr/local/lib, and they are not in the default include/lib path, so you should include them with -I & -L. 2f04e22b48517ca054ee347b8e5cbcfde339ffd3 309 308 2012-12-24T01:00:13Z HenryHu 1 wikitext text/x-wiki Various portability issues, mainly between linux/freebsd == prctl() / prctl.h == No prctl() in freebsd. * To set process title, use setproctitle() * For PR_SET_PTRACER, I'm not sure now. == malloc.h == Including malloc.h in freebsd leads to compile error. Use stdlib.h instead. Anyway, in linux's malloc(3) manpage, it is said that you should include stdlib.h. == libdl == In linux, dlopen()/dlclose()/dlsym() are in libdl. In freebsd, they are in libc. So there is no point to link with libdl, and there is no libdl, anyway. == program_invocation_short_name == No such thing in bsd. Maybe you should use argv[0]. == Include path / Lib path == freebsd installs all non-base softwares into '''/usr/local'''. So, the third party include files are in '''/usr/local/include''', and third party lib files are in '''/usr/local/lib''', and they are not in the default include/lib path, so you should include them with -I & -L. The modern way is to use pkg-config. You may also use cmake's FindXXX. c598f11249f4d6577bbcb046eb22aa9258403ef2 BBS数据接口 0 76 316 313 2013-01-22T15:03:21Z HenryHu 1 /* 获取帖子 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <string: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>}, "group": <int: Group ID, or 0 if not in a group, match with id>, "isdir": <boolean: is a board group> [optional], "child_count": <int: children count of the board group> [optional] } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |- | group || int || Board group to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes|| 帖子列表模式 |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, <*PostContent: content of the post>, 'attachlink': <string: URL of the page showing attachments. add '&a=offset' for individual attachment> } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> 35fda253a80ea53e958fb93a944186769d9bb1d8 317 316 2013-01-22T15:03:59Z HenryHu 1 /* 获取帖子 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <string: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>}, "group": <int: Group ID, or 0 if not in a group, match with id>, "isdir": <boolean: is a board group> [optional], "child_count": <int: children count of the board group> [optional] } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |- | group || int || Board group to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional || Choices |- | session || string || Session Token || No || |- | id || int || ID of the post in this board || No || |- | board || string || Name of the board this post belongs to || No || |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, <*PostContent: content of the post>, 'attachlink': <string: URL of the page showing attachments. add '&a=offset' for individual attachment> } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> 7205cf2cafe8d5b03806ad8e8d819bc693096c82 324 317 2013-06-11T08:12:19Z HenryHu 1 /* 发帖/回帖 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <string: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>}, "group": <int: Group ID, or 0 if not in a group, match with id>, "isdir": <boolean: is a board group> [optional], "child_count": <int: children count of the board group> [optional] } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |- | group || int || Board group to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional || Choices |- | session || string || Session Token || No || |- | id || int || ID of the post in this board || No || |- | board || string || Name of the board this post belongs to || No || |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 === 删帖 === : '''POST''' /post/delete {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to delete || Yes || |- | xid || int || unique ID of the post to delete || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以删自己的贴,版主可以删别人的贴。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, <*PostContent: content of the post>, 'attachlink': <string: URL of the page showing attachments. add '&a=offset' for individual attachment> } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> 02deef7eadd587bfe09f4b35eb17995ba046d46e 325 324 2013-06-13T06:46:00Z HenryHu 1 /* 帖子 */ deletable flag wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <string: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>}, "group": <int: Group ID, or 0 if not in a group, match with id>, "isdir": <boolean: is a board group> [optional], "child_count": <int: children count of the board group> [optional] } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |- | group || int || Board group to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g, deletable PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional || Choices |- | session || string || Session Token || No || |- | id || int || ID of the post in this board || No || |- | board || string || Name of the board this post belongs to || No || |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 === 删帖 === : '''POST''' /post/delete {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to delete || Yes || |- | xid || int || unique ID of the post to delete || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以删自己的贴,版主可以删别人的贴。 == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, <*PostContent: content of the post>, 'attachlink': <string: URL of the page showing attachments. add '&a=offset' for individual attachment> } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> 3571ac51a09b5602012e67b845436772b416f940 335 325 2013-06-16T07:36:04Z HenryHu 1 post/edit & post/search wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <string: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>}, "group": <int: Group ID, or 0 if not in a group, match with id>, "isdir": <boolean: is a board group> [optional], "child_count": <int: children count of the board group> [optional] } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |- | group || int || Board group to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g, deletable PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional || Choices |- | session || string || Session Token || No || |- | id || int || ID of the post in this board || No || |- | board || string || Name of the board this post belongs to || No || |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 === 删帖 === : '''POST''' /post/delete {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to delete || Yes || |- | xid || int || unique ID of the post to delete || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以删自己的贴,版主可以删别人的贴。 === 编辑 === : '''POST''' /post/edit {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to edit || Yes || |- | xid || int || unique ID of the post to edit || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |- | title || string || new title || Yes || 如果没有则不变 |- | content || string || new content || Yes || 如果没有则不变 |- | new_attachments || JSON encoded PostAttachInfo || Yes || 新的附件列表,参见发贴 |- | del_attachments || array<int> || attachments to remove || Yes || 要删除的附件编号,从0开始 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以编辑自己的贴,版主可以编辑别人的贴。 == 搜索 == : '''GET''' /post/search {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | from || int || search from this post || Yes || 默认从头开始 |- | forward || int || search forward || Yes || 0/1,默认向前搜索(1) |- | count || int || max number of search results || Yes || 默认返回一个结果 |- | query || JSON of search query || search query || No || 格式参见下文 |} query是一个表达式,基本形式为: [<op>, <arg1>, <arg2>, ...] 其中op为操作符。目前支持: * 逻辑操作符,每个参数都是一个表达式 ** or: 取所有参数结果的或 ** and: 取所有参数结果的与 ** not: 取所有参数结果的非,只能有一个参数 ** 样例 *** ['or', <expr1>, <expr2>, <expr3>] *** ['not', <expr>] * 字符串域匹配,有一个参数,为一个正则表达式 ** author: 匹配作者 ** title: 匹配标题 ** content: 匹配内容 ** 样例 *** ['author', 'henryhu'] *** ['title', 'hell.+orld'] * 标记匹配,没有参数 ** m: 被m帖子 ** g: 收精帖子 ** noreply: 不可回复帖子 ** has_attach: 有附件 ** 样例: ['m'] * 整数域匹配,第一个参数为域名,第二个参数为比较值 ** 操作符 *** ge: 大于等于 *** le: 小于等于 *** eq: 等于 ** 域名 *** posttime: 发帖时间 *** thread: 主题编号,主题贴xid *** size: 帖子大小 ** 样例 *** ['ge', 'posttime', <time, UTC+8 seconds>] *** ['eq', 'thread', 1234] == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, <*PostContent: content of the post>, 'attachlink': <string: URL of the page showing attachments. add '&a=offset' for individual attachment> } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> 84a2ab8c951c4641009a3c2229b0458f9ee1da89 336 335 2013-06-16T07:36:33Z HenryHu 1 /* 搜索 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <string: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>}, "group": <int: Group ID, or 0 if not in a group, match with id>, "isdir": <boolean: is a board group> [optional], "child_count": <int: children count of the board group> [optional] } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |- | group || int || Board group to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g, deletable PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional || Choices |- | session || string || Session Token || No || |- | id || int || ID of the post in this board || No || |- | board || string || Name of the board this post belongs to || No || |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 === 删帖 === : '''POST''' /post/delete {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to delete || Yes || |- | xid || int || unique ID of the post to delete || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以删自己的贴,版主可以删别人的贴。 === 编辑 === : '''POST''' /post/edit {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to edit || Yes || |- | xid || int || unique ID of the post to edit || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |- | title || string || new title || Yes || 如果没有则不变 |- | content || string || new content || Yes || 如果没有则不变 |- | new_attachments || JSON encoded PostAttachInfo || Yes || 新的附件列表,参见发贴 |- | del_attachments || array<int> || attachments to remove || Yes || 要删除的附件编号,从0开始 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以编辑自己的贴,版主可以编辑别人的贴。 === 搜索 === : '''GET''' /post/search {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | from || int || search from this post || Yes || 默认从头开始 |- | forward || int || search forward || Yes || 0/1,默认向前搜索(1) |- | count || int || max number of search results || Yes || 默认返回一个结果 |- | query || JSON of search query || search query || No || 格式参见下文 |} query是一个表达式,基本形式为: [<op>, <arg1>, <arg2>, ...] 其中op为操作符。目前支持: * 逻辑操作符,每个参数都是一个表达式 ** or: 取所有参数结果的或 ** and: 取所有参数结果的与 ** not: 取所有参数结果的非,只能有一个参数 ** 样例 *** ['or', <expr1>, <expr2>, <expr3>] *** ['not', <expr>] * 字符串域匹配,有一个参数,为一个正则表达式 ** author: 匹配作者 ** title: 匹配标题 ** content: 匹配内容 ** 样例 *** ['author', 'henryhu'] *** ['title', 'hell.+orld'] * 标记匹配,没有参数 ** m: 被m帖子 ** g: 收精帖子 ** noreply: 不可回复帖子 ** has_attach: 有附件 ** 样例: ['m'] * 整数域匹配,第一个参数为域名,第二个参数为比较值 ** 操作符 *** ge: 大于等于 *** le: 小于等于 *** eq: 等于 ** 域名 *** posttime: 发帖时间 *** thread: 主题编号,主题贴xid *** size: 帖子大小 ** 样例 *** ['ge', 'posttime', <time, UTC+8 seconds>] *** ['eq', 'thread', 1234] == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, <*PostContent: content of the post>, 'attachlink': <string: URL of the page showing attachments. add '&a=offset' for individual attachment> } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> 422cfa58d4516a7b2b3df1edefa2b04a4e42126d 337 336 2013-06-18T07:41:52Z HenryHu 1 /* 阅读邮件 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <string: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>}, "group": <int: Group ID, or 0 if not in a group, match with id>, "isdir": <boolean: is a board group> [optional], "child_count": <int: children count of the board group> [optional] } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |- | group || int || Board group to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g, deletable PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional || Choices |- | session || string || Session Token || No || |- | id || int || ID of the post in this board || No || |- | board || string || Name of the board this post belongs to || No || |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 === 删帖 === : '''POST''' /post/delete {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to delete || Yes || |- | xid || int || unique ID of the post to delete || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以删自己的贴,版主可以删别人的贴。 === 编辑 === : '''POST''' /post/edit {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to edit || Yes || |- | xid || int || unique ID of the post to edit || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |- | title || string || new title || Yes || 如果没有则不变 |- | content || string || new content || Yes || 如果没有则不变 |- | new_attachments || JSON encoded PostAttachInfo || Yes || 新的附件列表,参见发贴 |- | del_attachments || array<int> || attachments to remove || Yes || 要删除的附件编号,从0开始 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以编辑自己的贴,版主可以编辑别人的贴。 === 搜索 === : '''GET''' /post/search {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | from || int || search from this post || Yes || 默认从头开始 |- | forward || int || search forward || Yes || 0/1,默认向前搜索(1) |- | count || int || max number of search results || Yes || 默认返回一个结果 |- | query || JSON of search query || search query || No || 格式参见下文 |} query是一个表达式,基本形式为: [<op>, <arg1>, <arg2>, ...] 其中op为操作符。目前支持: * 逻辑操作符,每个参数都是一个表达式 ** or: 取所有参数结果的或 ** and: 取所有参数结果的与 ** not: 取所有参数结果的非,只能有一个参数 ** 样例 *** ['or', <expr1>, <expr2>, <expr3>] *** ['not', <expr>] * 字符串域匹配,有一个参数,为一个正则表达式 ** author: 匹配作者 ** title: 匹配标题 ** content: 匹配内容 ** 样例 *** ['author', 'henryhu'] *** ['title', 'hell.+orld'] * 标记匹配,没有参数 ** m: 被m帖子 ** g: 收精帖子 ** noreply: 不可回复帖子 ** has_attach: 有附件 ** 样例: ['m'] * 整数域匹配,第一个参数为域名,第二个参数为比较值 ** 操作符 *** ge: 大于等于 *** le: 小于等于 *** eq: 等于 ** 域名 *** posttime: 发帖时间 *** thread: 主题编号,主题贴xid *** size: 帖子大小 ** 样例 *** ['ge', 'posttime', <time, UTC+8 seconds>] *** ['eq', 'thread', 1234] == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, <*PostContent: content of the post>, 'attachlink': <string: URL of the page showing attachments. add '&a=offset' for individual attachment> } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> === 引用邮件 === : '''GET''' /mail/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || the folder of the quoted mail || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |- | mode || string || quote mode, same as post/quote || yes || '''S'''/R/N/A |} * Return value: <source lang="javascript"> { "title": <string: quoted title>, "content": <string: quoted content> } </source> 引用某个邮件箱里的某封邮件,可选引用模式。 === 发邮件 === : '''POST''' /mail/send {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | to || string || receiver id || no || |- | title || string || mail title || no || |- | content || string || mail content || no || |- | signature_id || int || signature id || yes || '''0(none)'''/-1(random)/>0 |- | save_in_sent || int || save the mail in the sent box || yes || '''1'''/0 |} * Return value: <source lang="javascript"> {"result": "ok"} </source> 发邮件,可选是否存发件箱。 如果需要引用邮件,请先调用/mail/quote。 cb254b033ef1b79a1a31fb46c3e51340922b5315 340 337 2013-10-19T21:56:40Z HenryHu 1 /* 获取帖子 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <string: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>}, "group": <int: Group ID, or 0 if not in a group, match with id>, "isdir": <boolean: is a board group> [optional], "child_count": <int: children count of the board group> [optional] } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |- | group || int || Board group to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g, deletable PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional || Choices |- | session || string || Session Token || No || |- | id || int || ID of the post in this board || No || |- | board || string || Name of the board this post belongs to || No || |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | start || int || Start from line No. || Yes || start >= 0 |- | count || int || Lines to fetch || Yes || count >= 0 |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 === 删帖 === : '''POST''' /post/delete {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to delete || Yes || |- | xid || int || unique ID of the post to delete || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以删自己的贴,版主可以删别人的贴。 === 编辑 === : '''POST''' /post/edit {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to edit || Yes || |- | xid || int || unique ID of the post to edit || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |- | title || string || new title || Yes || 如果没有则不变 |- | content || string || new content || Yes || 如果没有则不变 |- | new_attachments || JSON encoded PostAttachInfo || Yes || 新的附件列表,参见发贴 |- | del_attachments || array<int> || attachments to remove || Yes || 要删除的附件编号,从0开始 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以编辑自己的贴,版主可以编辑别人的贴。 === 搜索 === : '''GET''' /post/search {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | from || int || search from this post || Yes || 默认从头开始 |- | forward || int || search forward || Yes || 0/1,默认向前搜索(1) |- | count || int || max number of search results || Yes || 默认返回一个结果 |- | query || JSON of search query || search query || No || 格式参见下文 |} query是一个表达式,基本形式为: [<op>, <arg1>, <arg2>, ...] 其中op为操作符。目前支持: * 逻辑操作符,每个参数都是一个表达式 ** or: 取所有参数结果的或 ** and: 取所有参数结果的与 ** not: 取所有参数结果的非,只能有一个参数 ** 样例 *** ['or', <expr1>, <expr2>, <expr3>] *** ['not', <expr>] * 字符串域匹配,有一个参数,为一个正则表达式 ** author: 匹配作者 ** title: 匹配标题 ** content: 匹配内容 ** 样例 *** ['author', 'henryhu'] *** ['title', 'hell.+orld'] * 标记匹配,没有参数 ** m: 被m帖子 ** g: 收精帖子 ** noreply: 不可回复帖子 ** has_attach: 有附件 ** 样例: ['m'] * 整数域匹配,第一个参数为域名,第二个参数为比较值 ** 操作符 *** ge: 大于等于 *** le: 小于等于 *** eq: 等于 ** 域名 *** posttime: 发帖时间 *** thread: 主题编号,主题贴xid *** size: 帖子大小 ** 样例 *** ['ge', 'posttime', <time, UTC+8 seconds>] *** ['eq', 'thread', 1234] == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, <*PostContent: content of the post>, 'attachlink': <string: URL of the page showing attachments. add '&a=offset' for individual attachment> } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> === 引用邮件 === : '''GET''' /mail/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || the folder of the quoted mail || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |- | mode || string || quote mode, same as post/quote || yes || '''S'''/R/N/A |} * Return value: <source lang="javascript"> { "title": <string: quoted title>, "content": <string: quoted content> } </source> 引用某个邮件箱里的某封邮件,可选引用模式。 === 发邮件 === : '''POST''' /mail/send {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | to || string || receiver id || no || |- | title || string || mail title || no || |- | content || string || mail content || no || |- | signature_id || int || signature id || yes || '''0(none)'''/-1(random)/>0 |- | save_in_sent || int || save the mail in the sent box || yes || '''1'''/0 |} * Return value: <source lang="javascript"> {"result": "ok"} </source> 发邮件,可选是否存发件箱。 如果需要引用邮件,请先调用/mail/quote。 73c15daf18051c9f3c755a995ccb7505499e3322 BBS OAuth 0 77 318 315 2013-01-27T03:45:09Z HenryHu 1 /* 显示验证页面 */ wikitext text/x-wiki == 应用注册 == 先到/res/clients.html注册应用。 利用BBS账户登录之后,点击Register new client,填写各项信息。 * client_id: 应用标识 * client_secret: 用于验证应用(RFC6749 $2.3.1) * redirect uri: OAuth的重定向路径(RFC6749 $3.1.2) * name: 应用名字 * description: 应用说明 * logo: 图标 * website: 网站 * type: 能保证应用自身安全性的选confidential,一般选public(RFC6749 $2.1) * response type: (RFC6749 $3.1.1) ** 希望用authentication code模式的选code(RFC6749 $4.1) ** 希望用直接跳转给token模式的选token(RFC6749 $4.2) * grant type: ** 希望用authentication code模式的选authentication code(RFC6749 $4.1) ** 希望用密码登录的选password(RFC6749 $4.3, 目前禁止) ** 希望直接靠应用确认身份的选client credentials(RFC6749 $4.4, 目前禁止) ** 希望获取和使用refresh token的选refresh token(RFC6749 $6) 注册完成之后就可以作为这个应用登录了。也可以在此页面修改/删除应用信息。 == 登录 == === 显示验证页面 === : '''GET''' /auth/auth {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | redirect_uri || string || Redirection URI || No || displaycode |- | response_type || string || Preferred response type || No || code/token |- | client_id || string || Client ID of the client application || No || |- | state || string || Client state string || Yes || |} * 如果选token模式,会直接在登录成功之后重定向到$redirect_uri?access_token=<string: token>&token_type=<string: token type>&expires_in=<int: time before token expires>[&state=<string: client state>] * 如果选code模式,会跳转到$redirect_uri?code=<string: authorization code>[&state=<string: client state>],需要再进行下一步获取token。 * state 用于传递客户端信息。服务器会把客户端传过来的 state 原样加到重定向的参数里去。 === 获取Token === : '''GET/POST''' /auth/token {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | redirect_uri || string || Redirection URI, should match with previous requests || No |- | grant_type || string || Type of object to exchange token with || No || authorization_code/refresh_token |- | code || string || Authorization code, required for grant_type = authorization_code || Yes || |- | refresh_token || string || Refresh token, required for grant_type = refresh_token || Yes || |- | client_id || string || Client ID of the client application || No || |- | client_secret || string || Client secret of the client application || No || |} * Return value ** Success: {"access_token": <string: Token>, "token_type": <string: Token type>, ["refresh_token": <string: Refresh Token>,] "expires_in": <int: Seconds before expire> } ** Failure: various HTTP error code * refresh_token may be used to exchange for a new access_token and a new refresh_token, it will be disabled after the exchange * refresh_token可换取新access_token和refresh_token,换取后原refresh_token失效 49f36a2df07c7a7dba706d8aec7ce802636a1d44 Ef fan disc 破解 0 95 319 2013-02-25T01:40:35Z HenryHu 1 以内容“他毛的下了个硬盘版居然说不是正版不能用…… 观察了一下,这位读了win的序列号,估计是机器有关的,丫的谁做的硬盘版…...”创建新页面 wikitext text/x-wiki 他毛的下了个硬盘版居然说不是正版不能用…… 观察了一下,这位读了win的序列号,估计是机器有关的,丫的谁做的硬盘版…… 于是开始搞,挂上ollydbg,截messagebox,就抓到了…… 往回看看,抓到了第一个地方: 0x413b09 jnz short ef_fd_cn.00413b11 大约是比较序列号的正确性,之前读了serialcode和installkeycode 之后跑起来,注意到有debug string说啥CheckSelfIdentity(): filecrc=xxx, execrc=xxx之类,估计有自我校验。观察以后,把这个关掉: 0x47a996 mov esi,eax 这里把算出来的file crc移到esi里,之后会比较。因为正确的crc就在ebx里,直接改成mov esi, ebx就解决问题了。 接着跑着跑着居然就死循环了,看了一下,之前调了isdebuggerpresent()... 貌似还是动态从kernel32里抓出来的函数地址…… 0x41ae96 mov al,1 这个函数调了isdebuggerpresent, 这里返回1表示有,改成xor al,al就可以让他返回0…… 不过其实跑起来没关系,只是调的时候,如果是1,接着就会直接dead loop…… 接着不出一开始的错误框了,但是进去之后,硕大的血红色画面,里面说你用的是盗版…… 继续研究,发现之前判断完正版之后会把结果存起来,于是在存的地方下读取断点,还真找到了…… 进游戏居然又查一次…… 0x401353 jnz short ef_fd_cn.00401359 这个是比较InstallKeyCode和正确值,在这里可以直接抓到正确值,填进注册表就行了…… 最后就能跑了…… 347a2011e38d2657b4fe25e8cbe10f44a80db931 Ibus 0 96 320 2013-04-10T14:30:22Z HenryHu 1 以内容“== Apr 10, 2013 == === chinese/ibus-pinyin === This port is split into 2 parts. The database-related parts of the code are split into pyzy. So, a new port, chinese/py...”创建新页面 wikitext text/x-wiki == Apr 10, 2013 == === chinese/ibus-pinyin === This port is split into 2 parts. The database-related parts of the code are split into pyzy. So, a new port, chinese/pyzy is created. * New dependency: chinese/pyzy Build with Boost is fixed. The bug which prevents the ports from building with boost is fixed in 1.49. So now there is a new option, BOOST, which makes the port depends on boost-libs>=1.49 if enabled. pkg-plist updated. Dependency TODO? === chinese/pyzy === Almost done. pkg-plist & pkg-descr created. Dependency: (TODO) * glib2 * sqlite3 * uuid_create? * boost >= 1.39 (need 1.49 to build) === textproc/ibus === * some patch files removed. Already merged in upstream * some patch statements in Makefile removed. Already merged. * dependency updated. * patch: remove -Wno-unused-but-set-variable in engine & tools & ui/gtk3 Built & installed. Problems: * A bug in Xorg's XInput extension prevents GTK3 UI from starting. Need Xorg later than the version in the ports, or use WITH_NEW_XORG * py-gobject disabled introspection, which prevents setup app from starting * If introspection is enabled, then a new problem appears: py-gobject is too old, and it does not support GVariant, that prevents setup app from starting 01ab73425ec8c8cf671a5a0dc72678aa4915424c 321 320 2013-05-11T23:04:42Z HenryHu 1 /* textproc/ibus */ wikitext text/x-wiki == Apr 10, 2013 == === chinese/ibus-pinyin === This port is split into 2 parts. The database-related parts of the code are split into pyzy. So, a new port, chinese/pyzy is created. * New dependency: chinese/pyzy Build with Boost is fixed. The bug which prevents the ports from building with boost is fixed in 1.49. So now there is a new option, BOOST, which makes the port depends on boost-libs>=1.49 if enabled. pkg-plist updated. Dependency TODO? === chinese/pyzy === Almost done. pkg-plist & pkg-descr created. Dependency: (TODO) * glib2 * sqlite3 * uuid_create? * boost >= 1.39 (need 1.49 to build) === textproc/ibus === * some patch files removed. Already merged in upstream * some patch statements in Makefile removed. Already merged. * dependency updated. Built & installed. Problems: * A bug in Xorg's XInput extension prevents GTK3 UI from starting. Need Xorg later than the version in the ports, or use WITH_NEW_XORG 1bc79fe921ddcafc23cae2257123e943c688c815 341 321 2013-10-24T00:53:14Z HenryHu 1 wikitext text/x-wiki == Bugs == === ibus 1.5.4 * ibus-ui-gtk3 crash Reason unknown. * Can't change priority of imput methods == Apr 10, 2013 == === chinese/ibus-pinyin === This port is split into 2 parts. The database-related parts of the code are split into pyzy. So, a new port, chinese/pyzy is created. * New dependency: chinese/pyzy Build with Boost is fixed. The bug which prevents the ports from building with boost is fixed in 1.49. So now there is a new option, BOOST, which makes the port depends on boost-libs>=1.49 if enabled. pkg-plist updated. Dependency TODO? === chinese/pyzy === Almost done. pkg-plist & pkg-descr created. Dependency: (TODO) * glib2 * sqlite3 * uuid_create? * boost >= 1.39 (need 1.49 to build) === textproc/ibus === * some patch files removed. Already merged in upstream * some patch statements in Makefile removed. Already merged. * dependency updated. Built & installed. Problems: * A bug in Xorg's XInput extension prevents GTK3 UI from starting. Need Xorg later than the version in the ports, or use WITH_NEW_XORG b5326c64c19b9768c1381dc236b62c683969b2fe 342 341 2013-10-24T01:14:59Z HenryHu 1 /* Bugs */ wikitext text/x-wiki == Bugs == === ibus 1.5.4 === * ibus-ui-gtk3 crash Reason unknown. * Can't change priority of input methods Changing through dconf-editor only has temporary effect. == Apr 10, 2013 == === chinese/ibus-pinyin === This port is split into 2 parts. The database-related parts of the code are split into pyzy. So, a new port, chinese/pyzy is created. * New dependency: chinese/pyzy Build with Boost is fixed. The bug which prevents the ports from building with boost is fixed in 1.49. So now there is a new option, BOOST, which makes the port depends on boost-libs>=1.49 if enabled. pkg-plist updated. Dependency TODO? === chinese/pyzy === Almost done. pkg-plist & pkg-descr created. Dependency: (TODO) * glib2 * sqlite3 * uuid_create? * boost >= 1.39 (need 1.49 to build) === textproc/ibus === * some patch files removed. Already merged in upstream * some patch statements in Makefile removed. Already merged. * dependency updated. Built & installed. Problems: * A bug in Xorg's XInput extension prevents GTK3 UI from starting. Need Xorg later than the version in the ports, or use WITH_NEW_XORG ec1dacb4524783023cc21beba47938999b6b33bf Android PDF Reader 0 92 322 303 2013-05-13T19:15:38Z HenryHu 1 wikitext text/x-wiki {| class="wikitable" ! Application !! White-border removal !! Continuous scroll !! One-column mode !! Price !! Comment |- || ezPDF || {{No}} || {{No}} || {{Yes}} || Not Free || Used for a long time |- || Mantano Lite || {{Yes}} || {{Yes}} || {{Yes}} || Free || Meets all the requirements |- || Aldiko || {{No}} || {{No}} || {{No}} || Free || Not ready for PDF |- || Perfect Viewer || {{Yes}} || {{No}} || {{No}} || Free || In fact, this is an image viewer |- || Moon+ Reader Pro || ? || ? || ? || $4.99 || I use free version for txt reading |- || Orion Viewer || {{Yes}} || ? || {{No}} || Free || open-source |} 335d20ef56cde2c1108fe280dcbe0e878968f32d Elanbsd 0 97 323 2013-05-17T14:13:15Z HenryHu 1 以内容“elanBSD: write/port a driver for elan touchpad on bsd '''May 16''' Successsfully switched the psm device to native mode. Read bytes from touchpad OK. Detect OK. Check ...”创建新页面 wikitext text/x-wiki elanBSD: write/port a driver for elan touchpad on bsd '''May 16''' Successsfully switched the psm device to native mode. Read bytes from touchpad OK. Detect OK. Check version OK. Parse V4 packets OK. xdotool made. 52fe8429ea790c35df59a7a0961ec6e1f81a4dca BBS Project 0 78 326 201 2013-06-14T07:49:51Z HenryHu 1 /* 相关分析 */ wikitext text/x-wiki 构建一个现代化的BBS,吸引新用户使用,提高BBS体验,让各平台下都能够使用BBS。 == API接口 == * [[BBS数据接口]] : 提供BBS各项服务的接口。基于HTTP协议,数据格式为JSON。 * [[BBS XMPP接口]] : 提供另一部分BBS服务的接口,主要包括好友/在线信息/聊天功能。 : XMPP协议标准见 http://tools.ietf.org/html/rfc6120 以及 http://tools.ietf.org/html/rfc6121 ,具体参见 http://xmpp.org == 项目 == * [[Pybbs]] : 利用Python实现一个兼容KBS的BBS系统,提供API接口供各个平台下的客户端使用。 * [[Andwell]] : 在API接口的基础上,实现的Android平台下的客户端。 == 相关分析 == * [[:Category:BBS 代码分析]] : 对原有KBS代码的分析,便于开发出兼容于KBS系统的新系统。 == TODO == [[BBS Project TODO]] 3e5f939f5855165c9b1b6c54c68e1184cbb23b2b 329 326 2013-06-14T08:02:48Z HenryHu 1 /* 项目 */ 田甲其他客户端 wikitext text/x-wiki 构建一个现代化的BBS,吸引新用户使用,提高BBS体验,让各平台下都能够使用BBS。 == API接口 == * [[BBS数据接口]] : 提供BBS各项服务的接口。基于HTTP协议,数据格式为JSON。 * [[BBS XMPP接口]] : 提供另一部分BBS服务的接口,主要包括好友/在线信息/聊天功能。 : XMPP协议标准见 http://tools.ietf.org/html/rfc6120 以及 http://tools.ietf.org/html/rfc6121 ,具体参见 http://xmpp.org == 项目 == * [[Pybbs]] : 利用Python实现一个兼容KBS的BBS系统,提供API接口供各个平台下的客户端使用。 * [[Andwell]] : 在API接口的基础上,实现的Android平台下的客户端。 * [https://github.com/mrroach9/Rowell Rowell] : 网页版BBS客户端 * [https://github.com/Orange9/iWell iWell] : iOS版BBS客户端 == 相关分析 == * [[:Category:BBS 代码分析]] : 对原有KBS代码的分析,便于开发出兼容于KBS系统的新系统。 == TODO == [[BBS Project TODO]] 54618f828aa4030a7fa1b2d47103dae321716029 330 329 2013-06-14T08:03:21Z HenryHu 1 /* 项目 */ wikitext text/x-wiki 构建一个现代化的BBS,吸引新用户使用,提高BBS体验,让各平台下都能够使用BBS。 == API接口 == * [[BBS数据接口]] : 提供BBS各项服务的接口。基于HTTP协议,数据格式为JSON。 * [[BBS XMPP接口]] : 提供另一部分BBS服务的接口,主要包括好友/在线信息/聊天功能。 : XMPP协议标准见 http://tools.ietf.org/html/rfc6120 以及 http://tools.ietf.org/html/rfc6121 ,具体参见 http://xmpp.org == 项目 == * [[Pybbs]] : 利用Python实现一个兼容KBS的BBS系统,提供API接口供各个平台下的客户端使用。 * [[Andwell]] : 在API接口的基础上,实现的Android平台下的客户端。 * [https://github.com/mrroach9/Rowell Rowell] : 网页版BBS客户端, by Roach * [https://github.com/Orange9/iWell iWell] : iOS版BBS客户端, by Orange == 相关分析 == * [[:Category:BBS 代码分析]] : 对原有KBS代码的分析,便于开发出兼容于KBS系统的新系统。 == TODO == [[BBS Project TODO]] 5c125c3ba3499c45f44021242c1275e962a8fa70 BBS Project TODO 0 98 327 2013-06-14T07:54:53Z HenryHu 1 以内容“== PyBBS == * 寄信 * 修改个人设置(例如签名档) * 改贴 * 管理收藏夹 * 任意存储 * == AndWell * 删帖”创建新页面 wikitext text/x-wiki == PyBBS == * 寄信 * 修改个人设置(例如签名档) * 改贴 * 管理收藏夹 * 任意存储 * == AndWell * 删帖 8a352d6b5f0e1e110eeba2dc888f99b104309e64 328 327 2013-06-14T07:58:24Z HenryHu 1 /* PyBBS */ wikitext text/x-wiki == PyBBS == * 寄信 * 修改个人设置(例如签名档) * 改贴 * 管理收藏夹 * 任意存储 * 注册 * 标题搜索 * 发帖者搜索 * 内容搜索 * 十大 * 数据统计 == AndWell == * 删帖 e6ae2fc99361090e4a24bdad28f4f7af867984d6 331 328 2013-06-15T09:51:47Z HenryHu 1 /* PyBBS */ wikitext text/x-wiki == PyBBS == * 寄信 * 修改个人设置(例如签名档) * 改贴 [DONE] * 管理收藏夹 * 任意存储 * 注册 * 标题搜索 * 发帖者搜索 * 内容搜索 * 十大 * 数据统计 == AndWell == * 删帖 499cb254b25b758df485a9769fb530671117f34b 332 331 2013-06-16T03:37:48Z HenryHu 1 /* PyBBS */ wikitext text/x-wiki == PyBBS == * 寄信 * 修改个人设置(例如签名档) * 改贴 [DONE] * 管理收藏夹 * 任意存储 * 注册 * 标题搜索 * 发帖者搜索 * 内容搜索 * 十大 * 数据统计 * 转贴 * 发投票 == AndWell == * 删帖 83bce8a1a93d05345e8fad5f2d9bc33502e70722 333 332 2013-06-16T06:45:02Z HenryHu 1 /* PyBBS */ wikitext text/x-wiki == PyBBS == * 寄信 * 修改个人设置(例如签名档) * 改贴 [DONE] * 管理收藏夹 * 任意存储 * 注册 * 标题搜索 [DONE] * 发帖者搜索 [DONE] * 内容搜索 * 十大 * 数据统计 * 转贴 * 发投票 == AndWell == * 删帖 6740eb532a7341af201cda01df9bb7ecceb967e2 334 333 2013-06-16T07:16:44Z HenryHu 1 /* PyBBS */ wikitext text/x-wiki == PyBBS == * 寄信 * 修改个人设置(例如签名档) * 改贴 [DONE] * 管理收藏夹 * 任意存储 * 注册 * 标题搜索 [DONE] * 发帖者搜索 [DONE] * 内容搜索 [DONE] * 十大 * 数据统计 * 转贴 * 发投票 == AndWell == * 删帖 18b00f09d48ede68b4305defc7fba43c13acd5fe 338 334 2013-06-18T07:53:21Z HenryHu 1 /* PyBBS */ wikitext text/x-wiki == PyBBS == * 寄信 [DONE] * 修改个人设置(例如签名档) * 改贴 [DONE] * 管理收藏夹 * 任意存储 * 注册 * 标题搜索 [DONE] * 发帖者搜索 [DONE] * 内容搜索 [DONE] * 十大 * 数据统计 * 转贴 * 发投票 == AndWell == * 删帖 f497df57f8bb26dbb41e16edda077f1ac6f64ca1 Pure-FTPd 0 99 339 2013-09-14T06:50:01Z HenryHu 1 以内容“== Max User Number == It's not only controlled by MaxClientsNumber and MaxClientsPerIP. It's also limited by the number of passive ports. Max user number <= number of ...”创建新页面 wikitext text/x-wiki == Max User Number == It's not only controlled by MaxClientsNumber and MaxClientsPerIP. It's also limited by the number of passive ports. Max user number <= number of passive ports / 2. be46c233baa1252c5fc84932e70ed8a19602795c FreeBSD on UX51VZ 0 100 343 2013-11-15T03:26:46Z HenryHu 1 以内容“== Graphics == === Integrated: Intel Ivy Bridge GT 2 === Works: * Display * External VGA monitor Does not work: * Brightness adjustment === Discrete: NVidia GT 650M ...”创建新页面 wikitext text/x-wiki == Graphics == === Integrated: Intel Ivy Bridge GT 2 === Works: * Display * External VGA monitor Does not work: * Brightness adjustment === Discrete: NVidia GT 650M === Works: * Separate X server, output from HDMI Does not work: * Optimus * Same X server, output from HDMI == Sound == Works: * Onboard ALC663 Does not work: * Auto-switch when headphone is plugged in * Audio output through HDMI == Ethernet == Works: * Onboard Atheros AR8151 (alc) == WiFi == === Onboard Intel Advanced-N 6235 === Works: * 802.11b/g * 802.11n with 20MHz channel Does not work: * 802.11n with 40MHz channel == Storage == Works: * Intel RST Raid 0 == Boot == Works: * EFI (with projects/uefi branch) 774d9a9a4cde95a63ca9d7066ce21f368fa14faa 344 343 2013-11-15T18:54:28Z HenryHu 1 wikitext text/x-wiki == Graphics == === Integrated: Intel Ivy Bridge GT 2 === Works: * Display * External VGA monitor Does not work: * Brightness adjustment === Discrete: NVidia GT 650M === Works: * Separate X server, output from HDMI Does not work: * Optimus * Same X server, output from HDMI == Sound == Works: * Onboard ALC663 Does not work: * Auto-switch when headphone is plugged in ** I know how to make it work; but I prefer the current situation * Audio output through HDMI ** NVidia audio device does not show up == Ethernet == Works: * Onboard Atheros AR8151 (alc) ** 100/1000M both work == WiFi == === Onboard Intel Advanced-N 6235 === Works: * 802.11b/g * 802.11n with 20MHz channel Does not work: * 802.11n with 40MHz channel == Storage == Works: * Intel RST Raid 0 ** To boot from this configure, you need to boot with EFI == Boot == Works: * EFI (with projects/uefi branch) 1a79ac7d4aef331ba7377047aece745b8f2b8f5a 351 344 2014-02-11T00:52:48Z HenryHu 1 /* Integrated: Intel Ivy Bridge GT 2 */ wikitext text/x-wiki == Graphics == === Integrated: Intel Ivy Bridge GT 2 === Works: * Display * External VGA monitor * Brightness adjustment of internal LCD using intel-backlight in intel-gpu-tools === Discrete: NVidia GT 650M === Works: * Separate X server, output from HDMI Does not work: * Optimus * Same X server, output from HDMI == Sound == Works: * Onboard ALC663 Does not work: * Auto-switch when headphone is plugged in ** I know how to make it work; but I prefer the current situation * Audio output through HDMI ** NVidia audio device does not show up == Ethernet == Works: * Onboard Atheros AR8151 (alc) ** 100/1000M both work == WiFi == === Onboard Intel Advanced-N 6235 === Works: * 802.11b/g * 802.11n with 20MHz channel Does not work: * 802.11n with 40MHz channel == Storage == Works: * Intel RST Raid 0 ** To boot from this configure, you need to boot with EFI == Boot == Works: * EFI (with projects/uefi branch) 581f1f79834da7dc0cbda9d24235c92f317df3f4 352 351 2014-02-11T00:52:58Z HenryHu 1 /* Integrated: Intel Ivy Bridge GT 2 */ wikitext text/x-wiki == Graphics == === Integrated: Intel Ivy Bridge GT 2 === Works: * Display * External VGA monitor * Brightness adjustment of internal LCD using intel-backlight in intel-gpu-tools === Discrete: NVidia GT 650M === Works: * Separate X server, output from HDMI Does not work: * Optimus * Same X server, output from HDMI == Sound == Works: * Onboard ALC663 Does not work: * Auto-switch when headphone is plugged in ** I know how to make it work; but I prefer the current situation * Audio output through HDMI ** NVidia audio device does not show up == Ethernet == Works: * Onboard Atheros AR8151 (alc) ** 100/1000M both work == WiFi == === Onboard Intel Advanced-N 6235 === Works: * 802.11b/g * 802.11n with 20MHz channel Does not work: * 802.11n with 40MHz channel == Storage == Works: * Intel RST Raid 0 ** To boot from this configure, you need to boot with EFI == Boot == Works: * EFI (with projects/uefi branch) 8538e45ccce2d13725cac306453f5d83abe99748 Wine Font 0 101 345 2013-12-10T05:10:16Z HenryHu 1 以内容“关于如何在Wine里面配置字体,特别是中文字体。 == 调试信息 == 要看调试信息,跑 env WINEDEBUG=+font wine <program> 具体WINEDEBUG可...”创建新页面 wikitext text/x-wiki 关于如何在Wine里面配置字体,特别是中文字体。 == 调试信息 == 要看调试信息,跑 env WINEDEBUG=+font wine <program> 具体WINEDEBUG可以参见<ref>[http://wiki.winehq.org/DebugChannels Debug Logging]</ref>。 == 相关注册表位置 == 基本上在<ref name="reg">[http://wiki.winehq.org/UsefulRegistryKeys Useful Registry Keys]</ref>里面说了。 === HKEY_CURRENT_USER\Software\Wine\Fonts === 这里底下有几个: * Cache 底下有各个字体的信息的缓存,删掉这个分支也会自动重建,最多能暂时解决问题,没啥用。 里面可以查到各个字体名字。如果有English Name属性那也能作为名字用。 * External Fonts 字体列表,应该也是自动产生的 * Replacements 第一个可以用于替换字体的位置,在里面弄个字符串值,<要替换的>=<替换为>,就可以了。 据说如果能找到要替换的字体这个就不起作用,所以这也就是个 fallback 而已。 === HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion === 这里有另外几个相关的键值<ref name="reg"/>。 * FontLink/SystemLink 这里可以把字体和字体文件对应起来。 目前尝试貌似只能找到不带路径的字体,在Windows\Fonts目录里。也是字符串值,格式是<字体名>=<字体文件>。 例如,如果要让MS Sans Serif用微米黑,写 name: “MS Sans Serif” value: “wqy-microhei.ttc” 并把wqy-microhei.ttc放到windows的fonts目录就可以了。 * Fonts 系统级的字体列表,和上面的External Fonts貌似类似,可能也是自动生成的。 * FontSubstitutes 另一个可以替换字体的地方,格式和上面的Replacements一样。不过这里貌似不管实际字体存不存在都会替换。 另外,如果这里作为被替换的字体出现的话,上面SystemLink就会失效(废话……)。 == 配置方法 == 看了上面的可以知道,基本上只要搞SystemLink和FontSubstitutes就可以了。 SystemLink关联到字体文件,FontSubstitutes把别的字体替换成这个。 其实只要把要搞的字体都在SystemLink里关联了就完了。FontSubstitutes里有一堆系统默认搞了的。 貌似要搞的字体有: * Arial * Arial Black * Microsoft Sans Serif // 可能不需要 * MS Sans Serif // 需要 * SimSun * System // 谁知道呢…… * Tahoma * Tahoma Bold == 参见 == <references/> 3769d00270364d358fd46df3e71d968d6728638f Reservation 0 91 346 311 2014-01-15T00:06:07Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng 6c469881950b9b42c56e6d1a651f6582efeaf0f4 359 346 2014-04-25T23:40:10Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-17 || 2014-05-19? || Yongle Zhang || ? |- || 2014-05-30 || 2014-05-31? || Xu Zhao || Transit to SF |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng a4d0da484ad1fe2046daeb2fe304c31e692cc3f3 360 359 2014-04-29T18:18:25Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-15 || ? || Jingyue Wu || Thesis Defend |- || 2014-05-17 || 2014-05-19? || Yongle Zhang || ? |- || 2014-05-30 || 2014-05-31? || Xu Zhao || Transit to SF |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng 5d404ea69dd4b14fa3321912c9487244c0ff7c81 361 360 2014-05-05T19:27:28Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-08 || 2014-05-17 || Jingyue Wu || Thesis Defend |- || 2014-05-17 || 2014-05-19? || Yongle Zhang || ? |- || 2014-05-30 || 2014-05-31? || Xu Zhao || Transit to SF |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng 0a0f8de78b4779c8743c6f5224f5972b072b8af0 362 361 2014-05-06T20:21:31Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-08 || 2014-05-17 || Jingyue Wu || Thesis Defend |- || 2014-05-17 || 2014-05-19? || Yongle Zhang || ? |- || 2014-05-30 || 2014-05-31 || Xu Zhao || Transit to SF |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng 42162c7c8375e6cb234329db0b35abb8b348c2a8 363 362 2014-05-06T20:22:16Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-08 || 2014-05-17 || Jingyue Wu || Thesis Defend |- || 2014-05-17 || 2014-05-19? || Yongle Zhang || ? |- || 2014-05-30 || 2014-06-01 || Xu Zhao || Transit to SF |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng 985f68e7d94255bbf0c56b09dc44d9e75c036115 364 363 2014-05-20T21:07:54Z HenryHu 1 wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-08 || 2014-05-17 || Jingyue Wu || Thesis Defend |- || 2014-05-23 || 2014-05-25 || Ruizhang Jin || ? |- || 2014-05-30 || 2014-06-01 || Xu Zhao || Transit to SF |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng 7424fe491fdb7d66c5d6e32541cf138bf2904196 365 364 2014-05-23T22:18:45Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-08 || 2014-05-17 || Jingyue Wu || Thesis Defend |- || 2014-05-30 || 2014-06-01 || Xu Zhao || Transit to SF |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng 64ce972e7f09eb48df1165292a22746752ab28a2 Canada Visa 0 102 347 2014-02-06T20:50:34Z HenryHu 1 以内容“=== 在线申请 === === 提交护照 === 去Rockfeller Center的Consulate General of Canada提交护照。需要: 1. 确认信,在申请网站上打出来 2. 护...”创建新页面 wikitext text/x-wiki === 在线申请 === === 提交护照 === 去Rockfeller Center的Consulate General of Canada提交护照。需要: 1. 确认信,在申请网站上打出来 2. 护照 3. Prepaid USPS Express Mail Envelope,去边上的USPS(西北方向的Rockfeller Plaza边上,610号进去,在地下)。先拿一个Express Mail envelope,然后去self-service机子上,选Buy Stamp -> Priority Express Mail,反正最后是20刀,打出来一张邮票,贴在那个envelope上。然后拿一张Express Mail 的label,From填上 Consulate General of Canada in New York 1251 Avenue of the America, New York, NY 10020 电话是 212-596-1628 To填上自己的地址。 然后把label贴在envelope上。 去加拿大签证处,在6 Av (Avenue of the America) 和50街西边那个chase楼里。去chase楼侧面,进去,到地下,稍微绕一下就能看见visa office。进去和他说,然后投到一个类似寄信的邮桶里,就完了。 那里有个板子上写着等待时间,在线提交的貌似是5-7天。 cae8e2a4c2c5f9f2d1a912d72a7131b0ba20538c 348 347 2014-02-06T20:55:11Z HenryHu 1 /* 提交护照 */ wikitext text/x-wiki === 在线申请 === === 提交护照 === 去Rockfeller Center的Consulate General of Canada提交护照。需要: * 确认信,在申请网站上打出来 * 护照 * Prepaid USPS Express Mail Envelope,去边上的USPS(西北方向的Rockfeller Plaza边上,610号进去,在地下)。先拿一个Express Mail envelope,然后去self-service机子上,选Buy Stamp -> Priority Express Mail,反正最后是20刀,打出来一张邮票,贴在那个envelope上。然后拿一张Express Mail 的label,From填上 Consulate General of Canada in New York 1251 Avenue of the America, New York, NY 10020 电话是 212-596-1628 To填上自己的地址电话。 然后把label贴在envelope上。记得记下label上的tracking number(其实贴完label底下的基板上也有)。 去加拿大签证处,在6 Av (Avenue of the America) 和50街西边那个chase楼里。去chase楼侧面,进去,到地下,稍微绕一下就能看见visa office。进去和他说,然后投到一个类似寄信的邮桶里,就完了。 那里有个板子上写着等待时间,在线提交的貌似是5-7天。 c7949696edf17f7b1995ad53cab17cf00d3a6203 Startup Management 0 103 349 2014-02-10T19:53:35Z HenryHu 1 以内容“管理启动的时候跑什么东西的方法。 以下,假定操作对象为<service>。 == FreeBSD == * 要自动启动<service>: 编辑/etc/rc.conf,添加<se...”创建新页面 wikitext text/x-wiki 管理启动的时候跑什么东西的方法。 以下,假定操作对象为<service>。 == FreeBSD == * 要自动启动<service>: 编辑/etc/rc.conf,添加<service>_enable="YES" * 禁止启动<service>: 编辑/etc/rc.conf,删掉<service>_enable="YES",或者<service>_enable="NO" * 现在启动<service>: service <service> onestart * 现在停止<service>: service <service> onestop * 现在启动<service>(假设rc.conf里设置了自动启动): service <service> start * 现在停止<service>(假设rc.conf里设置了自动启动): service <service> stop == systemd == * 现在起动<service>: systemctl start <service> * 现在停止<service>: systemctl stop <service> * 自动启动<service>: systemctl enable <service> * 禁止自动启动<service>: systemctl disable <service> == SysV init == * 现在启动<service>: service <service> start * 现在停止<service>: service <service> stop * 自动启动<service>: update-rc.d <service> defaults * 禁止自动启动<service>: update-rc.d <service> remove == upstart == * 现在启动<service>: initctl <service> start * 现在停止<service>: initctl <service> stop * 自动启动<service>: 编辑/etc/init/<service>.conf,找到start on XXX,修改之,如 start on runlevel [2345] * 禁止自动启动<service>: 编辑/etc/init/<service>.conf,找到start on XXX,修改之,如 start on runlevel [] 8a5beea4a84cebcc5eba3a1f2b42254568e1f5d8 350 349 2014-02-10T20:00:45Z HenryHu 1 wikitext text/x-wiki 管理启动的时候跑什么东西的方法。 以下,假定操作对象为<service>。 == FreeBSD == * 要自动启动<service>: 编辑/etc/rc.conf,添加<service>_enable="YES" * 禁止启动<service>: 编辑/etc/rc.conf,删掉<service>_enable="YES",或者<service>_enable="NO" * 现在启动<service>: service <service> onestart * 现在停止<service>: service <service> onestop * 现在启动<service>(假设rc.conf里设置了自动启动): service <service> start * 现在停止<service>(假设rc.conf里设置了自动启动): service <service> stop * 检查<service>状态: service <service> status == systemd == * 现在起动<service>: systemctl start <service> * 现在停止<service>: systemctl stop <service> * 自动启动<service>: systemctl enable <service> * 禁止自动启动<service>: systemctl disable <service> * 检查<service>状态: systemctl status <service> == SysV init == * 现在启动<service>: service <service> start * 现在停止<service>: service <service> stop * 自动启动<service>: update-rc.d <service> defaults * 禁止自动启动<service>: update-rc.d <service> remove * 检查<service>状态: service <service> status == upstart == * 现在启动<service>: initctl start <service> * 现在停止<service>: initctl stop <service> * 自动启动<service>: 编辑/etc/init/<service>.conf,找到start on XXX,修改之,如 start on runlevel [2345] * 禁止自动启动<service>: 编辑/etc/init/<service>.conf,找到start on XXX,修改之,如 start on runlevel [] * 检查<service>状态: initctl status <service> 606a2f92798ff653a7993c0929af751f89b03a57 首页 0 1 353 204 2014-02-11T00:53:43Z HenryHu 1 wikitext text/x-wiki [[SubsConscious]] [[:Category:脚本|Scripts]] [[Package Management]] [[Startup Management]] [[Git Cheatsheet]] [[BBS Project]] <!-- == 入门 == * [http://www.mediawiki.org/wiki/Manual:Configuration_settings MediaWiki 配置设置列表] * [http://www.mediawiki.org/wiki/Manual:FAQ/zh-hans MediaWiki常见问题] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki发布邮件列表] --> f38cba2d0eda7ef0d87948f000765651ce31ac21 Connection Sharing 0 104 354 2014-03-05T23:45:00Z HenryHu 1 以“如何配连接共享。 === hostapd === 装hostapd,改配置,启动hostapd。 Example: <pre>systemctl start hostapd</pre> ==== hostapd.conf ==== <pre> interf...”为内容创建页面 wikitext text/x-wiki 如何配连接共享。 === hostapd === 装hostapd,改配置,启动hostapd。 Example: <pre>systemctl start hostapd</pre> ==== hostapd.conf ==== <pre> interface=<内网接口> ssid=<无线网名称> channel=<频道> ieee80211n=<启用802.11n? 1 : 0> ht_capab=<HT选项,见样例配置> wpa=<WPA选项,bitmask,WPA=1,WPA2=2> wpa_passphrase=<密码> wpa_key_mgmt=<密钥管理算法,可选WPA-PSK,WPA-EAP> wpa_pairwise=TKIP CCMP rsn_pairwise=CCMP </pre> === config IP === 给内网接口配个IP。 Example: <pre>ifconfig wlan0 192.168.1.1 netmask 255.255.255.0</pre> === dhcpd === 配置dhcpd.conf,然后 <pre>dhcpd <内网接口></pre> Example: <pre>dhcpd wlan0</pre> ==== dhcpd.conf ==== 建个对应内网网段的block,例如 <pre>subnet 192.168.1.0 netmask 255.255.255.0 { range 192.168.1.100 192.168.1.200; option routers 192.168.1.1; }</pre> 也可以再把外网列出来,以免不小心dhcpd对外网服务: <pre>subnet 128.59.16.0 netmask 255.255.248.0 { }</pre> 可以开authoritative,就会发DHCPNAK了。 === NAT === <pre>iptables -t nat -A POSTROUTING -s <内网网络>/<内网掩码长度> -o <外网接口> -j MASQUERADE</pre> Example: <pre>iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE</pre> b76f82d0fc8425046c96d2e0b13af31f43cc8a8b 355 354 2014-03-06T00:11:56Z HenryHu 1 /* NAT */ Enable IPv4 forwarding wikitext text/x-wiki 如何配连接共享。 === hostapd === 装hostapd,改配置,启动hostapd。 Example: <pre>systemctl start hostapd</pre> ==== hostapd.conf ==== <pre> interface=<内网接口> ssid=<无线网名称> channel=<频道> ieee80211n=<启用802.11n? 1 : 0> ht_capab=<HT选项,见样例配置> wpa=<WPA选项,bitmask,WPA=1,WPA2=2> wpa_passphrase=<密码> wpa_key_mgmt=<密钥管理算法,可选WPA-PSK,WPA-EAP> wpa_pairwise=TKIP CCMP rsn_pairwise=CCMP </pre> === config IP === 给内网接口配个IP。 Example: <pre>ifconfig wlan0 192.168.1.1 netmask 255.255.255.0</pre> === dhcpd === 配置dhcpd.conf,然后 <pre>dhcpd <内网接口></pre> Example: <pre>dhcpd wlan0</pre> ==== dhcpd.conf ==== 建个对应内网网段的block,例如 <pre>subnet 192.168.1.0 netmask 255.255.255.0 { range 192.168.1.100 192.168.1.200; option routers 192.168.1.1; }</pre> 也可以再把外网列出来,以免不小心dhcpd对外网服务: <pre>subnet 128.59.16.0 netmask 255.255.248.0 { }</pre> 可以开authoritative,就会发DHCPNAK了。 === NAT === <pre>sysctl net.ipv4.ip_forward=1 iptables -t nat -A POSTROUTING -s <内网网络>/<内网掩码长度> -o <外网接口> -j MASQUERADE</pre> Example: <pre>sysctl net.ipv4.ip_forward=1 iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE</pre> 5af2b7bffb0b4d3ded32b8f03bd8daef6771d455 356 355 2014-03-27T19:33:20Z HenryHu 1 wikitext text/x-wiki 如何配连接共享。 === rfkill === 如果rfkill开了,那没法发包,hostapd启动不了。 用<pre>rfkill list</pre>来看一下,只要有yes,那就需要<pre>rfkill unblock 0</pre>来关掉。 === hostapd === 装hostapd,改配置,启动hostapd。 Example: <pre>systemctl start hostapd</pre> ==== hostapd.conf ==== <pre> interface=<内网接口> ssid=<无线网名称> channel=<频道> ieee80211n=<启用802.11n? 1 : 0> ht_capab=<HT选项,见样例配置> wpa=<WPA选项,bitmask,WPA=1,WPA2=2> wpa_passphrase=<密码> wpa_key_mgmt=<密钥管理算法,可选WPA-PSK,WPA-EAP> wpa_pairwise=TKIP CCMP rsn_pairwise=CCMP </pre> === config IP === 给内网接口配个IP。 Example: <pre>ifconfig wlan0 192.168.1.1 netmask 255.255.255.0</pre> === dhcpd === 配置dhcpd.conf,然后 <pre>dhcpd <内网接口></pre> Example: <pre>dhcpd wlan0</pre> ==== dhcpd.conf ==== 建个对应内网网段的block,例如 <pre>subnet 192.168.1.0 netmask 255.255.255.0 { range 192.168.1.100 192.168.1.200; option routers 192.168.1.1; }</pre> 也可以再把外网列出来,以免不小心dhcpd对外网服务: <pre>subnet 128.59.16.0 netmask 255.255.248.0 { }</pre> 可以开authoritative,就会发DHCPNAK了。 === NAT === <pre>sysctl net.ipv4.ip_forward=1 iptables -t nat -A POSTROUTING -s <内网网络>/<内网掩码长度> -o <外网接口> -j MASQUERADE</pre> Example: <pre>sysctl net.ipv4.ip_forward=1 iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE</pre> fd6930342aeb9fe25abef95cc392865f8f403bb0 Xiami API 0 105 357 2014-04-24T20:12:48Z HenryHu 1 以“Xiami API reference / guess [[Xiami Radio API]]”为内容创建页面 wikitext text/x-wiki Xiami API reference / guess [[Xiami Radio API]] e569fbac4646037cc664efcd5bdd2a6eed2fb7e1 Xiami Radio API 0 106 358 2014-04-24T23:25:17Z HenryHu 1 以“== 符号 == * W: www.xiami.com * T: _xiamitoken * I: img.xiami.net == 获取电台歌曲列表 == W/radio/xml/type/<type>/id/<radio id>?v=<v> 目前还不清楚ty...”为内容创建页面 wikitext text/x-wiki == 符号 == * W: www.xiami.com * T: _xiamitoken * I: img.xiami.net == 获取电台歌曲列表 == W/radio/xml/type/<type>/id/<radio id>?v=<v> 目前还不清楚type是干嘛的…… v在电台页面有。 返回一个xml,前一段是用户信息,后一段是个歌曲数组。貌似每次调用给3个。 歌曲信息包括曲名、演唱者等等。其中location加密过,不过其实也就是排成一个表然后重排一下…… == 获取歌词 == W/radio/lyric?sid=<song id> 5d8a92357651132ea54107dd204c2f2d3e507f5f ACPI 0 107 366 2014-06-10T04:27:38Z HenryHu 1 以“=== WMI === http://msdn.microsoft.com/en-us/library/windows/hardware/dn614028%28v=vs.85%29.aspx Microsoft's WMI description”为内容创建页面 wikitext text/x-wiki === WMI === http://msdn.microsoft.com/en-us/library/windows/hardware/dn614028%28v=vs.85%29.aspx Microsoft's WMI description 266cc334aa7ef22ff68b9879b8a9ad6e8ab0c14a 367 366 2014-06-10T04:38:05Z HenryHu 1 wikitext text/x-wiki === WMI === http://msdn.microsoft.com/en-us/library/windows/hardware/dn614028%28v=vs.85%29.aspx Microsoft's WMI description http://www.nvidia.com/content/quadro_fx_product_literature/wp-06953-001-v02.pdf NVidia's NVWMI document cef78c40cd9dbf5c197ff1a28ab861b2e267e192 BBS数据接口 0 76 368 340 2014-06-15T09:59:46Z HenryHu 1 /* 用户 */ /user/register wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <string: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>}, "group": <int: Group ID, or 0 if not in a group, match with id>, "isdir": <boolean: is a board group> [optional], "child_count": <int: children count of the board group> [optional] } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |- | group || int || Board group to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g, deletable PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional || Choices |- | session || string || Session Token || No || |- | id || int || ID of the post in this board || No || |- | board || string || Name of the board this post belongs to || No || |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | start || int || Start from line No. || Yes || start >= 0 |- | count || int || Lines to fetch || Yes || count >= 0 |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 === 删帖 === : '''POST''' /post/delete {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to delete || Yes || |- | xid || int || unique ID of the post to delete || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以删自己的贴,版主可以删别人的贴。 === 编辑 === : '''POST''' /post/edit {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to edit || Yes || |- | xid || int || unique ID of the post to edit || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |- | title || string || new title || Yes || 如果没有则不变 |- | content || string || new content || Yes || 如果没有则不变 |- | new_attachments || JSON encoded PostAttachInfo || Yes || 新的附件列表,参见发贴 |- | del_attachments || array<int> || attachments to remove || Yes || 要删除的附件编号,从0开始 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以编辑自己的贴,版主可以编辑别人的贴。 === 搜索 === : '''GET''' /post/search {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | from || int || search from this post || Yes || 默认从头开始 |- | forward || int || search forward || Yes || 0/1,默认向前搜索(1) |- | count || int || max number of search results || Yes || 默认返回一个结果 |- | query || JSON of search query || search query || No || 格式参见下文 |} query是一个表达式,基本形式为: [<op>, <arg1>, <arg2>, ...] 其中op为操作符。目前支持: * 逻辑操作符,每个参数都是一个表达式 ** or: 取所有参数结果的或 ** and: 取所有参数结果的与 ** not: 取所有参数结果的非,只能有一个参数 ** 样例 *** ['or', <expr1>, <expr2>, <expr3>] *** ['not', <expr>] * 字符串域匹配,有一个参数,为一个正则表达式 ** author: 匹配作者 ** title: 匹配标题 ** content: 匹配内容 ** 样例 *** ['author', 'henryhu'] *** ['title', 'hell.+orld'] * 标记匹配,没有参数 ** m: 被m帖子 ** g: 收精帖子 ** noreply: 不可回复帖子 ** has_attach: 有附件 ** 样例: ['m'] * 整数域匹配,第一个参数为域名,第二个参数为比较值 ** 操作符 *** ge: 大于等于 *** le: 小于等于 *** eq: 等于 ** 域名 *** posttime: 发帖时间 *** thread: 主题编号,主题贴xid *** size: 帖子大小 ** 样例 *** ['ge', 'posttime', <time, UTC+8 seconds>] *** ['eq', 'thread', 1234] == 收藏夹 == === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard>, "type": <string: Type of this entry> }, ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, <*PostContent: content of the post>, 'attachlink': <string: URL of the page showing attachments. add '&a=offset' for individual attachment> } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> === 注册新用户 === : '''POST''' /user/register {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | username || string || User ID || No |- | password || string || Password || No |- | nick || string || Nick name || No |- | email || string || Email || No |- | realname || string || Real name || No |- | address || string || Address || No |- | birthyear || int || Birth year || No |- | birthmonth || int || Birth month || No |- | birthday || int || Birth day || No |- | gender || string || Gender (F/M) || No |- | selfintro || string || Self Introduction || Yes |- | phone || string || Contact information || No |- | career || string || Class information || No |} * Return value: <source lang="javascript"> {"result": "ok"} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> === 引用邮件 === : '''GET''' /mail/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || the folder of the quoted mail || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |- | mode || string || quote mode, same as post/quote || yes || '''S'''/R/N/A |} * Return value: <source lang="javascript"> { "title": <string: quoted title>, "content": <string: quoted content> } </source> 引用某个邮件箱里的某封邮件,可选引用模式。 === 发邮件 === : '''POST''' /mail/send {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | to || string || receiver id || no || |- | title || string || mail title || no || |- | content || string || mail content || no || |- | signature_id || int || signature id || yes || '''0(none)'''/-1(random)/>0 |- | save_in_sent || int || save the mail in the sent box || yes || '''1'''/0 |} * Return value: <source lang="javascript"> {"result": "ok"} </source> 发邮件,可选是否存发件箱。 如果需要引用邮件,请先调用/mail/quote。 76df0d5b4b1ae46a5c12d14ff963f0bdd0928146 375 368 2014-07-07T21:31:29Z HenryHu 1 /* 收藏夹 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <string: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>}, "group": <int: Group ID, or 0 if not in a group, match with id>, "isdir": <boolean: is a board group> [optional], "child_count": <int: children count of the board group> [optional] } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |- | group || int || Board group to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g, deletable PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional || Choices |- | session || string || Session Token || No || |- | id || int || ID of the post in this board || No || |- | board || string || Name of the board this post belongs to || No || |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | start || int || Start from line No. || Yes || start >= 0 |- | count || int || Lines to fetch || Yes || count >= 0 |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |} * Result ** {'nextid': <int: next post id in the thread>} * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 === 删帖 === : '''POST''' /post/delete {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to delete || Yes || |- | xid || int || unique ID of the post to delete || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以删自己的贴,版主可以删别人的贴。 === 编辑 === : '''POST''' /post/edit {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to edit || Yes || |- | xid || int || unique ID of the post to edit || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |- | title || string || new title || Yes || 如果没有则不变 |- | content || string || new content || Yes || 如果没有则不变 |- | new_attachments || JSON encoded PostAttachInfo || Yes || 新的附件列表,参见发贴 |- | del_attachments || array<int> || attachments to remove || Yes || 要删除的附件编号,从0开始 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以编辑自己的贴,版主可以编辑别人的贴。 === 搜索 === : '''GET''' /post/search {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | from || int || search from this post || Yes || 默认从头开始 |- | forward || int || search forward || Yes || 0/1,默认向前搜索(1) |- | count || int || max number of search results || Yes || 默认返回一个结果 |- | query || JSON of search query || search query || No || 格式参见下文 |} query是一个表达式,基本形式为: [<op>, <arg1>, <arg2>, ...] 其中op为操作符。目前支持: * 逻辑操作符,每个参数都是一个表达式 ** or: 取所有参数结果的或 ** and: 取所有参数结果的与 ** not: 取所有参数结果的非,只能有一个参数 ** 样例 *** ['or', <expr1>, <expr2>, <expr3>] *** ['not', <expr>] * 字符串域匹配,有一个参数,为一个正则表达式 ** author: 匹配作者 ** title: 匹配标题 ** content: 匹配内容 ** 样例 *** ['author', 'henryhu'] *** ['title', 'hell.+orld'] * 标记匹配,没有参数 ** m: 被m帖子 ** g: 收精帖子 ** noreply: 不可回复帖子 ** has_attach: 有附件 ** 样例: ['m'] * 整数域匹配,第一个参数为域名,第二个参数为比较值 ** 操作符 *** ge: 大于等于 *** le: 小于等于 *** eq: 等于 ** 域名 *** posttime: 发帖时间 *** thread: 主题编号,主题贴xid *** size: 帖子大小 ** 样例 *** ['ge', 'posttime', <time, UTC+8 seconds>] *** ['eq', 'thread', 1234] == 收藏夹 == FavBoardEntry: <source lang="javascript"> { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard, -1 for root entry>, "type": <string: Type of this entry, "board"/"dir"> } </source> === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first entry to list || Yes |- | end || int || ID of the last entry to list || Yes |- | count || int || Number of entries to list || Yes |} * Return value ** Success: <source lang="javascript"> [ FavBoardEntry, ... ] </source> === 列出某个项目的所有祖先项目 === : '''GET''' /favboard/dirnames {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | index || int || Index of the entry || No |} * Return value ** Success: <source lang="javascript"> [ FavBoardEntry, // the current entry FavBoardEntry, // its father FavBoardEntry, // its grandfather ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, <*PostContent: content of the post>, 'attachlink': <string: URL of the page showing attachments. add '&a=offset' for individual attachment> } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> === 注册新用户 === : '''POST''' /user/register {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | username || string || User ID || No |- | password || string || Password || No |- | nick || string || Nick name || No |- | email || string || Email || No |- | realname || string || Real name || No |- | address || string || Address || No |- | birthyear || int || Birth year || No |- | birthmonth || int || Birth month || No |- | birthday || int || Birth day || No |- | gender || string || Gender (F/M) || No |- | selfintro || string || Self Introduction || Yes |- | phone || string || Contact information || No |- | career || string || Class information || No |} * Return value: <source lang="javascript"> {"result": "ok"} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> === 引用邮件 === : '''GET''' /mail/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || the folder of the quoted mail || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |- | mode || string || quote mode, same as post/quote || yes || '''S'''/R/N/A |} * Return value: <source lang="javascript"> { "title": <string: quoted title>, "content": <string: quoted content> } </source> 引用某个邮件箱里的某封邮件,可选引用模式。 === 发邮件 === : '''POST''' /mail/send {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | to || string || receiver id || no || |- | title || string || mail title || no || |- | content || string || mail content || no || |- | signature_id || int || signature id || yes || '''0(none)'''/-1(random)/>0 |- | save_in_sent || int || save the mail in the sent box || yes || '''1'''/0 |} * Return value: <source lang="javascript"> {"result": "ok"} </source> 发邮件,可选是否存发件箱。 如果需要引用邮件,请先调用/mail/quote。 e3de902e24d14eadf35957f3302c8e77fefde169 378 375 2014-08-17T01:03:27Z HenryHu 1 /* 同主题浏览 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <string: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>}, "group": <int: Group ID, or 0 if not in a group, match with id>, "isdir": <boolean: is a board group> [optional], "child_count": <int: children count of the board group> [optional] } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |- | group || int || Board group to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g, deletable PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional || Choices |- | session || string || Session Token || No || |- | id || int || ID of the post in this board || No || |- | board || string || Name of the board this post belongs to || No || |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | start || int || Start from line No. || Yes || start >= 0 |- | count || int || Lines to fetch || Yes || count >= 0 |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |- | mode || string || how detailed the result should be || Yes || '''idonly'''/compact/detailed |} * Result ** If mode = idonly: ** {'nextid': <int: next post id in the thread>, 'nextxid': <int: next post's unique id>} ** If mode = compact/detailed: same as the result of /post/view * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 === 删帖 === : '''POST''' /post/delete {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to delete || Yes || |- | xid || int || unique ID of the post to delete || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以删自己的贴,版主可以删别人的贴。 === 编辑 === : '''POST''' /post/edit {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to edit || Yes || |- | xid || int || unique ID of the post to edit || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |- | title || string || new title || Yes || 如果没有则不变 |- | content || string || new content || Yes || 如果没有则不变 |- | new_attachments || JSON encoded PostAttachInfo || Yes || 新的附件列表,参见发贴 |- | del_attachments || array<int> || attachments to remove || Yes || 要删除的附件编号,从0开始 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以编辑自己的贴,版主可以编辑别人的贴。 === 搜索 === : '''GET''' /post/search {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | from || int || search from this post || Yes || 默认从头开始 |- | forward || int || search forward || Yes || 0/1,默认向前搜索(1) |- | count || int || max number of search results || Yes || 默认返回一个结果 |- | query || JSON of search query || search query || No || 格式参见下文 |} query是一个表达式,基本形式为: [<op>, <arg1>, <arg2>, ...] 其中op为操作符。目前支持: * 逻辑操作符,每个参数都是一个表达式 ** or: 取所有参数结果的或 ** and: 取所有参数结果的与 ** not: 取所有参数结果的非,只能有一个参数 ** 样例 *** ['or', <expr1>, <expr2>, <expr3>] *** ['not', <expr>] * 字符串域匹配,有一个参数,为一个正则表达式 ** author: 匹配作者 ** title: 匹配标题 ** content: 匹配内容 ** 样例 *** ['author', 'henryhu'] *** ['title', 'hell.+orld'] * 标记匹配,没有参数 ** m: 被m帖子 ** g: 收精帖子 ** noreply: 不可回复帖子 ** has_attach: 有附件 ** 样例: ['m'] * 整数域匹配,第一个参数为域名,第二个参数为比较值 ** 操作符 *** ge: 大于等于 *** le: 小于等于 *** eq: 等于 ** 域名 *** posttime: 发帖时间 *** thread: 主题编号,主题贴xid *** size: 帖子大小 ** 样例 *** ['ge', 'posttime', <time, UTC+8 seconds>] *** ['eq', 'thread', 1234] == 收藏夹 == FavBoardEntry: <source lang="javascript"> { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard, -1 for root entry>, "type": <string: Type of this entry, "board"/"dir"> } </source> === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first entry to list || Yes |- | end || int || ID of the last entry to list || Yes |- | count || int || Number of entries to list || Yes |} * Return value ** Success: <source lang="javascript"> [ FavBoardEntry, ... ] </source> === 列出某个项目的所有祖先项目 === : '''GET''' /favboard/dirnames {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | index || int || Index of the entry || No |} * Return value ** Success: <source lang="javascript"> [ FavBoardEntry, // the current entry FavBoardEntry, // its father FavBoardEntry, // its grandfather ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, <*PostContent: content of the post>, 'attachlink': <string: URL of the page showing attachments. add '&a=offset' for individual attachment> } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> === 注册新用户 === : '''POST''' /user/register {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | username || string || User ID || No |- | password || string || Password || No |- | nick || string || Nick name || No |- | email || string || Email || No |- | realname || string || Real name || No |- | address || string || Address || No |- | birthyear || int || Birth year || No |- | birthmonth || int || Birth month || No |- | birthday || int || Birth day || No |- | gender || string || Gender (F/M) || No |- | selfintro || string || Self Introduction || Yes |- | phone || string || Contact information || No |- | career || string || Class information || No |} * Return value: <source lang="javascript"> {"result": "ok"} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> === 引用邮件 === : '''GET''' /mail/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || the folder of the quoted mail || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |- | mode || string || quote mode, same as post/quote || yes || '''S'''/R/N/A |} * Return value: <source lang="javascript"> { "title": <string: quoted title>, "content": <string: quoted content> } </source> 引用某个邮件箱里的某封邮件,可选引用模式。 === 发邮件 === : '''POST''' /mail/send {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | to || string || receiver id || no || |- | title || string || mail title || no || |- | content || string || mail content || no || |- | signature_id || int || signature id || yes || '''0(none)'''/-1(random)/>0 |- | save_in_sent || int || save the mail in the sent box || yes || '''1'''/0 |} * Return value: <source lang="javascript"> {"result": "ok"} </source> 发邮件,可选是否存发件箱。 如果需要引用邮件,请先调用/mail/quote。 ac23d3fd08e95b50778c56946012ae62d44d3368 379 378 2014-08-17T01:04:02Z HenryHu 1 /* 同主题浏览 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <string: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>}, "group": <int: Group ID, or 0 if not in a group, match with id>, "isdir": <boolean: is a board group> [optional], "child_count": <int: children count of the board group> [optional] } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |- | group || int || Board group to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g, deletable PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional || Choices |- | session || string || Session Token || No || |- | id || int || ID of the post in this board || No || |- | board || string || Name of the board this post belongs to || No || |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | start || int || Start from line No. || Yes || start >= 0 |- | count || int || Lines to fetch || Yes || count >= 0 |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |- | mode || string || how detailed the result should be || Yes || '''idonly'''/compact/detailed |- | length || int || (only when mode=detailed) number of lines to return || Yes || |} * Result ** If mode = idonly: ** {'nextid': <int: next post id in the thread>, 'nextxid': <int: next post's unique id>} ** If mode = compact/detailed: same as the result of /post/view * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 === 删帖 === : '''POST''' /post/delete {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to delete || Yes || |- | xid || int || unique ID of the post to delete || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以删自己的贴,版主可以删别人的贴。 === 编辑 === : '''POST''' /post/edit {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to edit || Yes || |- | xid || int || unique ID of the post to edit || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |- | title || string || new title || Yes || 如果没有则不变 |- | content || string || new content || Yes || 如果没有则不变 |- | new_attachments || JSON encoded PostAttachInfo || Yes || 新的附件列表,参见发贴 |- | del_attachments || array<int> || attachments to remove || Yes || 要删除的附件编号,从0开始 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以编辑自己的贴,版主可以编辑别人的贴。 === 搜索 === : '''GET''' /post/search {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | from || int || search from this post || Yes || 默认从头开始 |- | forward || int || search forward || Yes || 0/1,默认向前搜索(1) |- | count || int || max number of search results || Yes || 默认返回一个结果 |- | query || JSON of search query || search query || No || 格式参见下文 |} query是一个表达式,基本形式为: [<op>, <arg1>, <arg2>, ...] 其中op为操作符。目前支持: * 逻辑操作符,每个参数都是一个表达式 ** or: 取所有参数结果的或 ** and: 取所有参数结果的与 ** not: 取所有参数结果的非,只能有一个参数 ** 样例 *** ['or', <expr1>, <expr2>, <expr3>] *** ['not', <expr>] * 字符串域匹配,有一个参数,为一个正则表达式 ** author: 匹配作者 ** title: 匹配标题 ** content: 匹配内容 ** 样例 *** ['author', 'henryhu'] *** ['title', 'hell.+orld'] * 标记匹配,没有参数 ** m: 被m帖子 ** g: 收精帖子 ** noreply: 不可回复帖子 ** has_attach: 有附件 ** 样例: ['m'] * 整数域匹配,第一个参数为域名,第二个参数为比较值 ** 操作符 *** ge: 大于等于 *** le: 小于等于 *** eq: 等于 ** 域名 *** posttime: 发帖时间 *** thread: 主题编号,主题贴xid *** size: 帖子大小 ** 样例 *** ['ge', 'posttime', <time, UTC+8 seconds>] *** ['eq', 'thread', 1234] == 收藏夹 == FavBoardEntry: <source lang="javascript"> { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard, -1 for root entry>, "type": <string: Type of this entry, "board"/"dir"> } </source> === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first entry to list || Yes |- | end || int || ID of the last entry to list || Yes |- | count || int || Number of entries to list || Yes |} * Return value ** Success: <source lang="javascript"> [ FavBoardEntry, ... ] </source> === 列出某个项目的所有祖先项目 === : '''GET''' /favboard/dirnames {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | index || int || Index of the entry || No |} * Return value ** Success: <source lang="javascript"> [ FavBoardEntry, // the current entry FavBoardEntry, // its father FavBoardEntry, // its grandfather ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, <*PostContent: content of the post>, 'attachlink': <string: URL of the page showing attachments. add '&a=offset' for individual attachment> } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> === 注册新用户 === : '''POST''' /user/register {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | username || string || User ID || No |- | password || string || Password || No |- | nick || string || Nick name || No |- | email || string || Email || No |- | realname || string || Real name || No |- | address || string || Address || No |- | birthyear || int || Birth year || No |- | birthmonth || int || Birth month || No |- | birthday || int || Birth day || No |- | gender || string || Gender (F/M) || No |- | selfintro || string || Self Introduction || Yes |- | phone || string || Contact information || No |- | career || string || Class information || No |} * Return value: <source lang="javascript"> {"result": "ok"} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> === 引用邮件 === : '''GET''' /mail/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || the folder of the quoted mail || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |- | mode || string || quote mode, same as post/quote || yes || '''S'''/R/N/A |} * Return value: <source lang="javascript"> { "title": <string: quoted title>, "content": <string: quoted content> } </source> 引用某个邮件箱里的某封邮件,可选引用模式。 === 发邮件 === : '''POST''' /mail/send {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | to || string || receiver id || no || |- | title || string || mail title || no || |- | content || string || mail content || no || |- | signature_id || int || signature id || yes || '''0(none)'''/-1(random)/>0 |- | save_in_sent || int || save the mail in the sent box || yes || '''1'''/0 |} * Return value: <source lang="javascript"> {"result": "ok"} </source> 发邮件,可选是否存发件箱。 如果需要引用邮件,请先调用/mail/quote。 c7d19fea6a74abfb6633c5a46f557443679d5cb3 380 379 2014-08-17T01:12:53Z HenryHu 1 /* 获取帖子列表 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <string: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>}, "group": <int: Group ID, or 0 if not in a group, match with id>, "isdir": <boolean: is a board group> [optional], "child_count": <int: children count of the board group> [optional] } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |- | group || int || Board group to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 获取同主题帖子列表 === : '''GET''' /board/thread_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || how detailed the result should be || Yes || '''idonly'''/compact/detailed |- | start || int || where to start the listing || Yes || |- | count || int || how many posts to list || Yes || |- | tid || int || id of the thread to list || No || |- | max_lines || int || (only in detailed mode) max number of lines to return || Yes || |} * Return value ** mode == idonly: ** <source lang="javascript"> { result: 'ok', list: [ { id: <int: post id>, xid: <int: unique post id> }, ... ] } </source> ** mode == compact / detailed: <source lang="javascript"> { result: 'ok', list: [ <same as /post/view>, ... ] } === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g, deletable PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional || Choices |- | session || string || Session Token || No || |- | id || int || ID of the post in this board || No || |- | board || string || Name of the board this post belongs to || No || |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | start || int || Start from line No. || Yes || start >= 0 |- | count || int || Lines to fetch || Yes || count >= 0 |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |- | mode || string || how detailed the result should be || Yes || '''idonly'''/compact/detailed |- | length || int || (only when mode=detailed) number of lines to return || Yes || |} * Result ** If mode = idonly: ** {'nextid': <int: next post id in the thread>, 'nextxid': <int: next post's unique id>} ** If mode = compact/detailed: same as the result of /post/view * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 === 删帖 === : '''POST''' /post/delete {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to delete || Yes || |- | xid || int || unique ID of the post to delete || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以删自己的贴,版主可以删别人的贴。 === 编辑 === : '''POST''' /post/edit {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to edit || Yes || |- | xid || int || unique ID of the post to edit || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |- | title || string || new title || Yes || 如果没有则不变 |- | content || string || new content || Yes || 如果没有则不变 |- | new_attachments || JSON encoded PostAttachInfo || Yes || 新的附件列表,参见发贴 |- | del_attachments || array<int> || attachments to remove || Yes || 要删除的附件编号,从0开始 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以编辑自己的贴,版主可以编辑别人的贴。 === 搜索 === : '''GET''' /post/search {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | from || int || search from this post || Yes || 默认从头开始 |- | forward || int || search forward || Yes || 0/1,默认向前搜索(1) |- | count || int || max number of search results || Yes || 默认返回一个结果 |- | query || JSON of search query || search query || No || 格式参见下文 |} query是一个表达式,基本形式为: [<op>, <arg1>, <arg2>, ...] 其中op为操作符。目前支持: * 逻辑操作符,每个参数都是一个表达式 ** or: 取所有参数结果的或 ** and: 取所有参数结果的与 ** not: 取所有参数结果的非,只能有一个参数 ** 样例 *** ['or', <expr1>, <expr2>, <expr3>] *** ['not', <expr>] * 字符串域匹配,有一个参数,为一个正则表达式 ** author: 匹配作者 ** title: 匹配标题 ** content: 匹配内容 ** 样例 *** ['author', 'henryhu'] *** ['title', 'hell.+orld'] * 标记匹配,没有参数 ** m: 被m帖子 ** g: 收精帖子 ** noreply: 不可回复帖子 ** has_attach: 有附件 ** 样例: ['m'] * 整数域匹配,第一个参数为域名,第二个参数为比较值 ** 操作符 *** ge: 大于等于 *** le: 小于等于 *** eq: 等于 ** 域名 *** posttime: 发帖时间 *** thread: 主题编号,主题贴xid *** size: 帖子大小 ** 样例 *** ['ge', 'posttime', <time, UTC+8 seconds>] *** ['eq', 'thread', 1234] == 收藏夹 == FavBoardEntry: <source lang="javascript"> { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard, -1 for root entry>, "type": <string: Type of this entry, "board"/"dir"> } </source> === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first entry to list || Yes |- | end || int || ID of the last entry to list || Yes |- | count || int || Number of entries to list || Yes |} * Return value ** Success: <source lang="javascript"> [ FavBoardEntry, ... ] </source> === 列出某个项目的所有祖先项目 === : '''GET''' /favboard/dirnames {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | index || int || Index of the entry || No |} * Return value ** Success: <source lang="javascript"> [ FavBoardEntry, // the current entry FavBoardEntry, // its father FavBoardEntry, // its grandfather ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, <*PostContent: content of the post>, 'attachlink': <string: URL of the page showing attachments. add '&a=offset' for individual attachment> } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> === 注册新用户 === : '''POST''' /user/register {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | username || string || User ID || No |- | password || string || Password || No |- | nick || string || Nick name || No |- | email || string || Email || No |- | realname || string || Real name || No |- | address || string || Address || No |- | birthyear || int || Birth year || No |- | birthmonth || int || Birth month || No |- | birthday || int || Birth day || No |- | gender || string || Gender (F/M) || No |- | selfintro || string || Self Introduction || Yes |- | phone || string || Contact information || No |- | career || string || Class information || No |} * Return value: <source lang="javascript"> {"result": "ok"} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> === 引用邮件 === : '''GET''' /mail/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || the folder of the quoted mail || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |- | mode || string || quote mode, same as post/quote || yes || '''S'''/R/N/A |} * Return value: <source lang="javascript"> { "title": <string: quoted title>, "content": <string: quoted content> } </source> 引用某个邮件箱里的某封邮件,可选引用模式。 === 发邮件 === : '''POST''' /mail/send {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | to || string || receiver id || no || |- | title || string || mail title || no || |- | content || string || mail content || no || |- | signature_id || int || signature id || yes || '''0(none)'''/-1(random)/>0 |- | save_in_sent || int || save the mail in the sent box || yes || '''1'''/0 |} * Return value: <source lang="javascript"> {"result": "ok"} </source> 发邮件,可选是否存发件箱。 如果需要引用邮件,请先调用/mail/quote。 d1ba52b3b7f3e8f285c81ca2da43726be4e24a55 381 380 2014-08-17T01:13:08Z HenryHu 1 /* 同主题浏览 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <string: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>}, "group": <int: Group ID, or 0 if not in a group, match with id>, "isdir": <boolean: is a board group> [optional], "child_count": <int: children count of the board group> [optional] } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |- | group || int || Board group to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 获取同主题帖子列表 === : '''GET''' /board/thread_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || how detailed the result should be || Yes || '''idonly'''/compact/detailed |- | start || int || where to start the listing || Yes || |- | count || int || how many posts to list || Yes || |- | tid || int || id of the thread to list || No || |- | max_lines || int || (only in detailed mode) max number of lines to return || Yes || |} * Return value ** mode == idonly: ** <source lang="javascript"> { result: 'ok', list: [ { id: <int: post id>, xid: <int: unique post id> }, ... ] } </source> ** mode == compact / detailed: <source lang="javascript"> { result: 'ok', list: [ <same as /post/view>, ... ] } === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g, deletable PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional || Choices |- | session || string || Session Token || No || |- | id || int || ID of the post in this board || No || |- | board || string || Name of the board this post belongs to || No || |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | start || int || Start from line No. || Yes || start >= 0 |- | count || int || Lines to fetch || Yes || count >= 0 |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |- | mode || string || how detailed the result should be || Yes || '''idonly'''/compact/detailed |- | max_lines || int || (only when mode=detailed) number of lines to return || Yes || |} * Result ** If mode = idonly: ** {'nextid': <int: next post id in the thread>, 'nextxid': <int: next post's unique id>} ** If mode = compact/detailed: same as the result of /post/view * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 === 删帖 === : '''POST''' /post/delete {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to delete || Yes || |- | xid || int || unique ID of the post to delete || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以删自己的贴,版主可以删别人的贴。 === 编辑 === : '''POST''' /post/edit {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to edit || Yes || |- | xid || int || unique ID of the post to edit || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |- | title || string || new title || Yes || 如果没有则不变 |- | content || string || new content || Yes || 如果没有则不变 |- | new_attachments || JSON encoded PostAttachInfo || Yes || 新的附件列表,参见发贴 |- | del_attachments || array<int> || attachments to remove || Yes || 要删除的附件编号,从0开始 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以编辑自己的贴,版主可以编辑别人的贴。 === 搜索 === : '''GET''' /post/search {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | from || int || search from this post || Yes || 默认从头开始 |- | forward || int || search forward || Yes || 0/1,默认向前搜索(1) |- | count || int || max number of search results || Yes || 默认返回一个结果 |- | query || JSON of search query || search query || No || 格式参见下文 |} query是一个表达式,基本形式为: [<op>, <arg1>, <arg2>, ...] 其中op为操作符。目前支持: * 逻辑操作符,每个参数都是一个表达式 ** or: 取所有参数结果的或 ** and: 取所有参数结果的与 ** not: 取所有参数结果的非,只能有一个参数 ** 样例 *** ['or', <expr1>, <expr2>, <expr3>] *** ['not', <expr>] * 字符串域匹配,有一个参数,为一个正则表达式 ** author: 匹配作者 ** title: 匹配标题 ** content: 匹配内容 ** 样例 *** ['author', 'henryhu'] *** ['title', 'hell.+orld'] * 标记匹配,没有参数 ** m: 被m帖子 ** g: 收精帖子 ** noreply: 不可回复帖子 ** has_attach: 有附件 ** 样例: ['m'] * 整数域匹配,第一个参数为域名,第二个参数为比较值 ** 操作符 *** ge: 大于等于 *** le: 小于等于 *** eq: 等于 ** 域名 *** posttime: 发帖时间 *** thread: 主题编号,主题贴xid *** size: 帖子大小 ** 样例 *** ['ge', 'posttime', <time, UTC+8 seconds>] *** ['eq', 'thread', 1234] == 收藏夹 == FavBoardEntry: <source lang="javascript"> { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard, -1 for root entry>, "type": <string: Type of this entry, "board"/"dir"> } </source> === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first entry to list || Yes |- | end || int || ID of the last entry to list || Yes |- | count || int || Number of entries to list || Yes |} * Return value ** Success: <source lang="javascript"> [ FavBoardEntry, ... ] </source> === 列出某个项目的所有祖先项目 === : '''GET''' /favboard/dirnames {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | index || int || Index of the entry || No |} * Return value ** Success: <source lang="javascript"> [ FavBoardEntry, // the current entry FavBoardEntry, // its father FavBoardEntry, // its grandfather ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, <*PostContent: content of the post>, 'attachlink': <string: URL of the page showing attachments. add '&a=offset' for individual attachment> } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> === 注册新用户 === : '''POST''' /user/register {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | username || string || User ID || No |- | password || string || Password || No |- | nick || string || Nick name || No |- | email || string || Email || No |- | realname || string || Real name || No |- | address || string || Address || No |- | birthyear || int || Birth year || No |- | birthmonth || int || Birth month || No |- | birthday || int || Birth day || No |- | gender || string || Gender (F/M) || No |- | selfintro || string || Self Introduction || Yes |- | phone || string || Contact information || No |- | career || string || Class information || No |} * Return value: <source lang="javascript"> {"result": "ok"} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> === 引用邮件 === : '''GET''' /mail/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || the folder of the quoted mail || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |- | mode || string || quote mode, same as post/quote || yes || '''S'''/R/N/A |} * Return value: <source lang="javascript"> { "title": <string: quoted title>, "content": <string: quoted content> } </source> 引用某个邮件箱里的某封邮件,可选引用模式。 === 发邮件 === : '''POST''' /mail/send {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | to || string || receiver id || no || |- | title || string || mail title || no || |- | content || string || mail content || no || |- | signature_id || int || signature id || yes || '''0(none)'''/-1(random)/>0 |- | save_in_sent || int || save the mail in the sent box || yes || '''1'''/0 |} * Return value: <source lang="javascript"> {"result": "ok"} </source> 发邮件,可选是否存发件箱。 如果需要引用邮件,请先调用/mail/quote。 b4a53037364692083b269913b14fb74ecb8b6189 382 381 2014-08-17T21:07:27Z HenryHu 1 /* 获取同主题帖子列表 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <string: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>}, "group": <int: Group ID, or 0 if not in a group, match with id>, "isdir": <boolean: is a board group> [optional], "child_count": <int: children count of the board group> [optional] } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |- | group || int || Board group to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 获取同主题帖子列表 === : '''GET''' /board/thread_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || how detailed the result should be || Yes || '''idonly'''/compact/detailed |- | start || int || where to start the listing || Yes || |- | count || int || how many posts to list || Yes || |- | tid || int || id of the thread to list || No || |- | max_lines || int || (only in detailed mode) max number of lines to return || Yes || |} * Return value ** mode == idonly: ** <source lang="javascript"> { result: 'ok', list: [ { id: <int: post id>, xid: <int: unique post id> }, ... ] } </source> ** mode == compact / detailed: <source lang="javascript"> { result: 'ok', list: [ <same as /post/view>, ... ] } </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g, deletable PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional || Choices |- | session || string || Session Token || No || |- | id || int || ID of the post in this board || No || |- | board || string || Name of the board this post belongs to || No || |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | start || int || Start from line No. || Yes || start >= 0 |- | count || int || Lines to fetch || Yes || count >= 0 |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |- | mode || string || how detailed the result should be || Yes || '''idonly'''/compact/detailed |- | max_lines || int || (only when mode=detailed) number of lines to return || Yes || |} * Result ** If mode = idonly: ** {'nextid': <int: next post id in the thread>, 'nextxid': <int: next post's unique id>} ** If mode = compact/detailed: same as the result of /post/view * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 === 删帖 === : '''POST''' /post/delete {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to delete || Yes || |- | xid || int || unique ID of the post to delete || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以删自己的贴,版主可以删别人的贴。 === 编辑 === : '''POST''' /post/edit {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to edit || Yes || |- | xid || int || unique ID of the post to edit || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |- | title || string || new title || Yes || 如果没有则不变 |- | content || string || new content || Yes || 如果没有则不变 |- | new_attachments || JSON encoded PostAttachInfo || Yes || 新的附件列表,参见发贴 |- | del_attachments || array<int> || attachments to remove || Yes || 要删除的附件编号,从0开始 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以编辑自己的贴,版主可以编辑别人的贴。 === 搜索 === : '''GET''' /post/search {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | from || int || search from this post || Yes || 默认从头开始 |- | forward || int || search forward || Yes || 0/1,默认向前搜索(1) |- | count || int || max number of search results || Yes || 默认返回一个结果 |- | query || JSON of search query || search query || No || 格式参见下文 |} query是一个表达式,基本形式为: [<op>, <arg1>, <arg2>, ...] 其中op为操作符。目前支持: * 逻辑操作符,每个参数都是一个表达式 ** or: 取所有参数结果的或 ** and: 取所有参数结果的与 ** not: 取所有参数结果的非,只能有一个参数 ** 样例 *** ['or', <expr1>, <expr2>, <expr3>] *** ['not', <expr>] * 字符串域匹配,有一个参数,为一个正则表达式 ** author: 匹配作者 ** title: 匹配标题 ** content: 匹配内容 ** 样例 *** ['author', 'henryhu'] *** ['title', 'hell.+orld'] * 标记匹配,没有参数 ** m: 被m帖子 ** g: 收精帖子 ** noreply: 不可回复帖子 ** has_attach: 有附件 ** 样例: ['m'] * 整数域匹配,第一个参数为域名,第二个参数为比较值 ** 操作符 *** ge: 大于等于 *** le: 小于等于 *** eq: 等于 ** 域名 *** posttime: 发帖时间 *** thread: 主题编号,主题贴xid *** size: 帖子大小 ** 样例 *** ['ge', 'posttime', <time, UTC+8 seconds>] *** ['eq', 'thread', 1234] == 收藏夹 == FavBoardEntry: <source lang="javascript"> { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard, -1 for root entry>, "type": <string: Type of this entry, "board"/"dir"> } </source> === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first entry to list || Yes |- | end || int || ID of the last entry to list || Yes |- | count || int || Number of entries to list || Yes |} * Return value ** Success: <source lang="javascript"> [ FavBoardEntry, ... ] </source> === 列出某个项目的所有祖先项目 === : '''GET''' /favboard/dirnames {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | index || int || Index of the entry || No |} * Return value ** Success: <source lang="javascript"> [ FavBoardEntry, // the current entry FavBoardEntry, // its father FavBoardEntry, // its grandfather ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, <*PostContent: content of the post>, 'attachlink': <string: URL of the page showing attachments. add '&a=offset' for individual attachment> } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> === 注册新用户 === : '''POST''' /user/register {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | username || string || User ID || No |- | password || string || Password || No |- | nick || string || Nick name || No |- | email || string || Email || No |- | realname || string || Real name || No |- | address || string || Address || No |- | birthyear || int || Birth year || No |- | birthmonth || int || Birth month || No |- | birthday || int || Birth day || No |- | gender || string || Gender (F/M) || No |- | selfintro || string || Self Introduction || Yes |- | phone || string || Contact information || No |- | career || string || Class information || No |} * Return value: <source lang="javascript"> {"result": "ok"} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> === 引用邮件 === : '''GET''' /mail/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || the folder of the quoted mail || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |- | mode || string || quote mode, same as post/quote || yes || '''S'''/R/N/A |} * Return value: <source lang="javascript"> { "title": <string: quoted title>, "content": <string: quoted content> } </source> 引用某个邮件箱里的某封邮件,可选引用模式。 === 发邮件 === : '''POST''' /mail/send {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | to || string || receiver id || no || |- | title || string || mail title || no || |- | content || string || mail content || no || |- | signature_id || int || signature id || yes || '''0(none)'''/-1(random)/>0 |- | save_in_sent || int || save the mail in the sent box || yes || '''1'''/0 |} * Return value: <source lang="javascript"> {"result": "ok"} </source> 发邮件,可选是否存发件箱。 如果需要引用邮件,请先调用/mail/quote。 18b11d08a226652234398cdf8d8a1b3c3735b23c CEB 0 108 369 2014-06-19T10:55:01Z HenryHu 1 以“== Objects == * cebiesign <pre> <object id="cebiesign" name="cebiesign" classid="clsid:f3e92562-1b4d-4bfa-b2d4-e9bcabe3b5a8" codebase="js/cebiesign.ocx#version=2,0,0...”为内容创建页面 wikitext text/x-wiki == Objects == * cebiesign <pre> <object id="cebiesign" name="cebiesign" classid="clsid:f3e92562-1b4d-4bfa-b2d4-e9bcabe3b5a8" codebase="js/cebiesign.ocx#version=2,0,0,4" border="0"> </object> </pre> * powercommit <pre> <object id="powercommit" codebase="js/PowerEnter.CAB#version=1,0,0,72" classid="clsid:BEEE2807-1709-4184-A05D-1B2DE01EE4CF" style="width:0px;height:0px" height="0" width="0"> <param name="width" value="0"> <param name="height" value="0"> <param name="frameName" value="mainFrame"> </object> </pre> * powerpassword <pre> <object id="powerpassword" codebase="js/PowerEnter.CAB#version=1,0,0,72" classid="clsid:614E58F9-74D0-4D7B-90E3-64A0F2AA73B4" style="width:186pxpx;height:23pxpx" height="23px" width="186px"> <param name="width" value="186px"> <param name="height" value="23px"> <param name="maxLength" value="20"> <param name="minLength" value="0"> <param name="maskChar" value="*"> <param name="backColor" value="#FFFFFF"> <param name="textColor" value="#000000"> <param name="borderColor" value="#7f9db9"> <param name="accepts" value="*"> <param name="msgBox" value="false"> <param name="fieldName" value="Password"> </object> </pre> == Commit Code == <source lang="javascript"> var blob ="BgIAAACkAABSU0ExAAQAAAEAAQAfFsbhRXwKJMLpsGExRSNaUxLZhaHvMp9ZJEgO2sa30lj6jc2BkNrF/35TKQuLphYVYwDLADdbRj23ChSzVWVmQwAs9CXrqR3tcYavKGsRBEeHEFctULIt6QFn/1Gz6F11k61K8G9yMXy9AGgN+pHum2X3EODpRJBFH9/w1VC+1w=="; function doLogin() { var ran = "<random value>"; if(ran != null && ran !="") { var random = parseFloat(ran)+1; document.form1.ran.value = random; } else { document.form1.ran.value = 0; } var powercommit = document.getElementById("powercommit"); var powerpassword = document.getElementById("powerpassword"); powercommit.reset(); powerpassword.publicKeyBlob(blob); powerpassword.commit("powercommit"); powercommit.submit("form1"); } </source> == Form Params == <source lang="html5"> <form name="form1" action="perlogin1.do" method="post"> <input type="hidden" name="_viewReferer" value="login/login01" /> <input type="hidden" name="_locale" value="zh_CN" /> <input type="hidden" name="version" value="20140529" /> <input type="hidden" name="Password" /> <input type="hidden" name="ran" value="063319703" /> <input type="hidden" name="TransName" value="" /> <input type="hidden" name="Plain" value="" /> <input type="hidden" name="Signature" value="" /> <input type="hidden" name="MerName" value="" /> <input type="hidden" name="TransType" value="" /> <input type="hidden" name="OperationNo" value="" /> <input type="hidden" name="MerDCFlag" value="" /> <input type="hidden" name="checkloginflag" value="" /> <input type="hidden" name="_tokenName" value="1jjihb5u" /> <div class="box"> <!--头部--> <div class=" head"><table cellpadding="0" cellspacing="0" border="0" style="margin:10px 0;"><tr><td align="left" ><img src="images/public/login_2.gif" /></td> </tr> </table> </div> <!--头部结束--> <!--内容--> <div class="content"> <table cellpadding="0" cellspacing="0" border="0"> <tr> <td class="conback" valign="top" > </td> <td class="conback2" valign="top" align="center"> <!--登录区--> <table cellpadding="0" cellspacing="0" border="0" class="login" width="433"> <tr><td valign="top" class="title line01" align="left"><img src="images/public/yhdl.gif" width="120" height="22" /> <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="1" height="1" id="flash" align="middle"> <param name="allowScriptAccess" value="sameDomain"/> <param name="movie" value="/per/bharosa_web/flash/bharosa.swf"/> <param name="quality" value="low"/> <param name="bgcolor" value="#ffffff"/> <param name=FlashVars value="dcUrl=/dc?s=true&"/> <embed src="/per/bharosa_web/flash/bharosa.swf" quality="low" bgcolor="#ffffff" FlashVars="dcUrl=/dc?s=true&" width="1" height="1"name="flash" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash"/> </object> </td></tr> <tr><td height="35" align="center"> </td></tr> <tr><td align="left"> <table cellpadding="0" cellspacing="3" border="0" width="100%"> <tr> <td class="size01 txt02" align="right" width="120">登录名或账号:&nbsp;&nbsp;</td> <td align="left" height="32" width="190"><input name="LoginName" id="skey" value="" class="input_out3" onfocus="this.className='input_on3';this.onmouseout=''" onblur="this.className='input_off3';this.onmouseout=function(){this.className='input_out3'};" type="text" size="16" /></td> <td width="100">&nbsp;</td> </tr> <tr> <td class="size01 txt02" align="right" width="120">登录密码:<img src="images/public/wen.gif" alt="请输入您设置的8~14位网银登录密码"/></td> <td align="left" height="32"> <script type="text/javascript">writePassObject("powerpassword",{"fieldName":"Password","maxLength":"20","minLength":"0","width":"186px","height":"23px","msgBox":"false","maskChar":"*","borderColor":"#7f9db9"});</script> </td> <td align="left"> <a href="####" class="txt_line txt07" onclick="MM_openBrWindow('pwdHelp.do','个人网上银行常见问题解答','width=640,height=420')">密码输入帮助</a> <img id="image1" src="tokenImage.xx?_timesShowToken=2&ran=063319703" style="display:none"/> </td> </tr> <tr><td colspan="3" height="10"></td></tr> <tr><td colspan="3" align="center"> <img src="images/public/denglu_1.gif" onclick="doLogin();" style="cursor: hand"/>&nbsp;&nbsp;&nbsp;&nbsp; </td></tr> </table> </td></tr> <tr><td height="23"></td></tr> <tr><td class="txt08" align="center"><a href="FP320501.do" class="txt07 txt_line">找回登录名</a> | <a href="FP320301.do" class="txt07 txt_line">忘记登录密码</a> | <a href="FP990101.do?ident=gr&idper=ds" class="txt07 txt_line">我要开通网银</a> </td></tr> </table> <!--登录区结束--> </td> </tr> </table> </form> </source> == Sample Form == * username = 11111111 * password = 22222222 4f5fde0f397a0850e338dea222f3d9f29218be2d 370 369 2014-06-19T10:56:43Z HenryHu 1 /* Sample Form */ wikitext text/x-wiki == Objects == * cebiesign <pre> <object id="cebiesign" name="cebiesign" classid="clsid:f3e92562-1b4d-4bfa-b2d4-e9bcabe3b5a8" codebase="js/cebiesign.ocx#version=2,0,0,4" border="0"> </object> </pre> * powercommit <pre> <object id="powercommit" codebase="js/PowerEnter.CAB#version=1,0,0,72" classid="clsid:BEEE2807-1709-4184-A05D-1B2DE01EE4CF" style="width:0px;height:0px" height="0" width="0"> <param name="width" value="0"> <param name="height" value="0"> <param name="frameName" value="mainFrame"> </object> </pre> * powerpassword <pre> <object id="powerpassword" codebase="js/PowerEnter.CAB#version=1,0,0,72" classid="clsid:614E58F9-74D0-4D7B-90E3-64A0F2AA73B4" style="width:186pxpx;height:23pxpx" height="23px" width="186px"> <param name="width" value="186px"> <param name="height" value="23px"> <param name="maxLength" value="20"> <param name="minLength" value="0"> <param name="maskChar" value="*"> <param name="backColor" value="#FFFFFF"> <param name="textColor" value="#000000"> <param name="borderColor" value="#7f9db9"> <param name="accepts" value="*"> <param name="msgBox" value="false"> <param name="fieldName" value="Password"> </object> </pre> == Commit Code == <source lang="javascript"> var blob ="BgIAAACkAABSU0ExAAQAAAEAAQAfFsbhRXwKJMLpsGExRSNaUxLZhaHvMp9ZJEgO2sa30lj6jc2BkNrF/35TKQuLphYVYwDLADdbRj23ChSzVWVmQwAs9CXrqR3tcYavKGsRBEeHEFctULIt6QFn/1Gz6F11k61K8G9yMXy9AGgN+pHum2X3EODpRJBFH9/w1VC+1w=="; function doLogin() { var ran = "<random value>"; if(ran != null && ran !="") { var random = parseFloat(ran)+1; document.form1.ran.value = random; } else { document.form1.ran.value = 0; } var powercommit = document.getElementById("powercommit"); var powerpassword = document.getElementById("powerpassword"); powercommit.reset(); powerpassword.publicKeyBlob(blob); powerpassword.commit("powercommit"); powercommit.submit("form1"); } </source> == Form Params == <source lang="html5"> <form name="form1" action="perlogin1.do" method="post"> <input type="hidden" name="_viewReferer" value="login/login01" /> <input type="hidden" name="_locale" value="zh_CN" /> <input type="hidden" name="version" value="20140529" /> <input type="hidden" name="Password" /> <input type="hidden" name="ran" value="063319703" /> <input type="hidden" name="TransName" value="" /> <input type="hidden" name="Plain" value="" /> <input type="hidden" name="Signature" value="" /> <input type="hidden" name="MerName" value="" /> <input type="hidden" name="TransType" value="" /> <input type="hidden" name="OperationNo" value="" /> <input type="hidden" name="MerDCFlag" value="" /> <input type="hidden" name="checkloginflag" value="" /> <input type="hidden" name="_tokenName" value="1jjihb5u" /> <div class="box"> <!--头部--> <div class=" head"><table cellpadding="0" cellspacing="0" border="0" style="margin:10px 0;"><tr><td align="left" ><img src="images/public/login_2.gif" /></td> </tr> </table> </div> <!--头部结束--> <!--内容--> <div class="content"> <table cellpadding="0" cellspacing="0" border="0"> <tr> <td class="conback" valign="top" > </td> <td class="conback2" valign="top" align="center"> <!--登录区--> <table cellpadding="0" cellspacing="0" border="0" class="login" width="433"> <tr><td valign="top" class="title line01" align="left"><img src="images/public/yhdl.gif" width="120" height="22" /> <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="1" height="1" id="flash" align="middle"> <param name="allowScriptAccess" value="sameDomain"/> <param name="movie" value="/per/bharosa_web/flash/bharosa.swf"/> <param name="quality" value="low"/> <param name="bgcolor" value="#ffffff"/> <param name=FlashVars value="dcUrl=/dc?s=true&"/> <embed src="/per/bharosa_web/flash/bharosa.swf" quality="low" bgcolor="#ffffff" FlashVars="dcUrl=/dc?s=true&" width="1" height="1"name="flash" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash"/> </object> </td></tr> <tr><td height="35" align="center"> </td></tr> <tr><td align="left"> <table cellpadding="0" cellspacing="3" border="0" width="100%"> <tr> <td class="size01 txt02" align="right" width="120">登录名或账号:&nbsp;&nbsp;</td> <td align="left" height="32" width="190"><input name="LoginName" id="skey" value="" class="input_out3" onfocus="this.className='input_on3';this.onmouseout=''" onblur="this.className='input_off3';this.onmouseout=function(){this.className='input_out3'};" type="text" size="16" /></td> <td width="100">&nbsp;</td> </tr> <tr> <td class="size01 txt02" align="right" width="120">登录密码:<img src="images/public/wen.gif" alt="请输入您设置的8~14位网银登录密码"/></td> <td align="left" height="32"> <script type="text/javascript">writePassObject("powerpassword",{"fieldName":"Password","maxLength":"20","minLength":"0","width":"186px","height":"23px","msgBox":"false","maskChar":"*","borderColor":"#7f9db9"});</script> </td> <td align="left"> <a href="####" class="txt_line txt07" onclick="MM_openBrWindow('pwdHelp.do','个人网上银行常见问题解答','width=640,height=420')">密码输入帮助</a> <img id="image1" src="tokenImage.xx?_timesShowToken=2&ran=063319703" style="display:none"/> </td> </tr> <tr><td colspan="3" height="10"></td></tr> <tr><td colspan="3" align="center"> <img src="images/public/denglu_1.gif" onclick="doLogin();" style="cursor: hand"/>&nbsp;&nbsp;&nbsp;&nbsp; </td></tr> </table> </td></tr> <tr><td height="23"></td></tr> <tr><td class="txt08" align="center"><a href="FP320501.do" class="txt07 txt_line">找回登录名</a> | <a href="FP320301.do" class="txt07 txt_line">忘记登录密码</a> | <a href="FP990101.do?ident=gr&idper=ds" class="txt07 txt_line">我要开通网银</a> </td></tr> </table> <!--登录区结束--> </td> </tr> </table> </form> </source> == Sample Form == * username = 11111111 * password = 22222222 <source lang="xml"> <entry method="POST" url="https://www.cebbank.com/per/perlogin1.do"> <timestart>2014-06-19T06:00:43.594Z</timestart> <timeend>2014-06-19T06:00:44.064Z</timeend> <duration>0.470 s</duration> <processname>C:\Program Files\Internet Explorer\iexplore.exe</processname> <result>200 OK</result> <size>0</size> <stage>REQUEST_CLOSE</stage> <mimetype>text/html</mimetype> <redirecturl/> <requestCamefromCache>False</requestCamefromCache> <responseCamefromCache>False</responseCamefromCache> <requestobjectname>/per/perlogin1.do</requestobjectname> <winet_sr_result>True</winet_sr_result> <winet_sr_errormessage/> <bodySize>9333</bodySize> <Web_PageID>0</Web_PageID> <PageTitle/> <Socket_SendSize>0</Socket_SendSize> <Socket_RecvSize>0</Socket_RecvSize> <Starred>False</Starred> <Comment/> <headers> <requestheaders> <header>POST /per/perlogin1.do HTTP/1.1</header> <header>Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, */*</header> <header>Referer: https://www.cebbank.com/per/prePerlogin.do?_locale=zh_CN</header> <header>Accept-Language: en-us</header> <header>User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)</header> <header>Content-Type: application/x-www-form-urlencoded</header> <header>Accept-Encoding: gzip, deflate</header> <header>Host: www.cebbank.com</header> <header>Connection: Keep-Alive</header> <header>Cache-Control: no-cache</header> <header>Cookie: WT_FPC=id=2b3fd12fcdda9131eb91403212946597:lv=1403212951284:ss=1403212946597; cebmemberbranchcode=3550; cebmemberbranchname=%u5317%u4EAC%u5206%u884C; PERJSESSIONID=t6m9Tv0cW5s9jN7JhXFLBhvsbwnG9h4gLn0pyqKgDp97tnNPxdpC!-2124310495; BIGipServerpool_eb_8005=2366482624.17695.0000</header> <header>Content-Length: 388</header> </requestheaders> <responseheaders> <header>HTTP/1.1 200 OK</header> <header>Server: Sun-Java-System-Web-Server/7.0</header> <header>Date: Thu, 19 Jun 2014 10:01:06 GMT</header> <header>Cache-Control: no-cache</header> <header>Date: Thu, 19 Jun 2014 09:59:58 GMT</header> <header>Pragma: No-cache</header> <header>Content-type: text/html; charset=gbk</header> <header>Expires: Thu, 01 Jan 1970 00:00:00 GMT</header> <header>Content-Language: zh-CN</header> <header>X-Powered-By: Servlet/2.5 JSP/2.1</header> <header>Connection: Keep-alive</header> <header>Via: 1.1 AN-0001544151441131</header> <header>Content-Length: 9333</header> </responseheaders> </headers> <content> <contentLength>9333</contentLength> <mimetype>text/html</mimetype> </content> <cookies> <sent> <cookie name=" WT_FPC">id=2b3fd12fcdda9131eb91403212946597:lv=1403212951284:ss=1403212946597</cookie> <cookie name=" cebmemberbranchcode">3550</cookie> <cookie name=" cebmemberbranchname">&#177;&#177;&#190;&#169;&#183;&#214;&#208;&#208;</cookie> <cookie name=" PERJSESSIONID">t6m9Tv0cW5s9jN7JhXFLBhvsbwnG9h4gLn0pyqKgDp97tnNPxdpC!-2124310495</cookie> <cookie name=" BIGipServerpool_eb_8005">2366482624.17695.0000</cookie> </sent> <received/> </cookies> <cache> <BeforeRequest> <UrlInCache>False</UrlInCache> </BeforeRequest> <AfterRequest> <UrlInCache>False</UrlInCache> </AfterRequest> </cache> <QueryString/> <PostData> <mimetype>application/x-www-form-urlencoded</mimetype> <size>388</size> <params> <param name="_viewReferer">login/login01</param> <param name="_locale">zh_CN</param> <param name="version">20140529</param> <param name="Password">XQn0aqYKjJeFutYuXaooFuDF7cAU7jAYd4lpIff/qaZOd1gElxbw/ChRmY1mipjeUlpO0lO8FHO13VaeEyaQf54np25wFo6X2t0LlAKKpruupbDHEWas3pVuajAXsuUqsyqSeDqNlsXpckRWdFBopnzoKuggcgkaMLXsyJtGLU8=</param> <param name="ran">55924190</param> <param name="TransName"/> <param name="Plain"/> <param name="Signature"/> <param name="MerName"/> <param name="TransType"/> <param name="OperationNo"/> <param name="MerDCFlag"/> <param name="checkloginflag"/> <param name="_tokenName">z90qww5h</param> <param name="LoginName">11111111</param> </params> </entry> </source> 074cc8e40c64470eebad61df4c667e89deb1d185 371 370 2014-06-19T12:38:34Z HenryHu 1 /* Sample Form */ wikitext text/x-wiki == Objects == * cebiesign <pre> <object id="cebiesign" name="cebiesign" classid="clsid:f3e92562-1b4d-4bfa-b2d4-e9bcabe3b5a8" codebase="js/cebiesign.ocx#version=2,0,0,4" border="0"> </object> </pre> * powercommit <pre> <object id="powercommit" codebase="js/PowerEnter.CAB#version=1,0,0,72" classid="clsid:BEEE2807-1709-4184-A05D-1B2DE01EE4CF" style="width:0px;height:0px" height="0" width="0"> <param name="width" value="0"> <param name="height" value="0"> <param name="frameName" value="mainFrame"> </object> </pre> * powerpassword <pre> <object id="powerpassword" codebase="js/PowerEnter.CAB#version=1,0,0,72" classid="clsid:614E58F9-74D0-4D7B-90E3-64A0F2AA73B4" style="width:186pxpx;height:23pxpx" height="23px" width="186px"> <param name="width" value="186px"> <param name="height" value="23px"> <param name="maxLength" value="20"> <param name="minLength" value="0"> <param name="maskChar" value="*"> <param name="backColor" value="#FFFFFF"> <param name="textColor" value="#000000"> <param name="borderColor" value="#7f9db9"> <param name="accepts" value="*"> <param name="msgBox" value="false"> <param name="fieldName" value="Password"> </object> </pre> == Commit Code == <source lang="javascript"> var blob ="BgIAAACkAABSU0ExAAQAAAEAAQAfFsbhRXwKJMLpsGExRSNaUxLZhaHvMp9ZJEgO2sa30lj6jc2BkNrF/35TKQuLphYVYwDLADdbRj23ChSzVWVmQwAs9CXrqR3tcYavKGsRBEeHEFctULIt6QFn/1Gz6F11k61K8G9yMXy9AGgN+pHum2X3EODpRJBFH9/w1VC+1w=="; function doLogin() { var ran = "<random value>"; if(ran != null && ran !="") { var random = parseFloat(ran)+1; document.form1.ran.value = random; } else { document.form1.ran.value = 0; } var powercommit = document.getElementById("powercommit"); var powerpassword = document.getElementById("powerpassword"); powercommit.reset(); powerpassword.publicKeyBlob(blob); powerpassword.commit("powercommit"); powercommit.submit("form1"); } </source> == Form Params == <source lang="html5"> <form name="form1" action="perlogin1.do" method="post"> <input type="hidden" name="_viewReferer" value="login/login01" /> <input type="hidden" name="_locale" value="zh_CN" /> <input type="hidden" name="version" value="20140529" /> <input type="hidden" name="Password" /> <input type="hidden" name="ran" value="063319703" /> <input type="hidden" name="TransName" value="" /> <input type="hidden" name="Plain" value="" /> <input type="hidden" name="Signature" value="" /> <input type="hidden" name="MerName" value="" /> <input type="hidden" name="TransType" value="" /> <input type="hidden" name="OperationNo" value="" /> <input type="hidden" name="MerDCFlag" value="" /> <input type="hidden" name="checkloginflag" value="" /> <input type="hidden" name="_tokenName" value="1jjihb5u" /> <div class="box"> <!--头部--> <div class=" head"><table cellpadding="0" cellspacing="0" border="0" style="margin:10px 0;"><tr><td align="left" ><img src="images/public/login_2.gif" /></td> </tr> </table> </div> <!--头部结束--> <!--内容--> <div class="content"> <table cellpadding="0" cellspacing="0" border="0"> <tr> <td class="conback" valign="top" > </td> <td class="conback2" valign="top" align="center"> <!--登录区--> <table cellpadding="0" cellspacing="0" border="0" class="login" width="433"> <tr><td valign="top" class="title line01" align="left"><img src="images/public/yhdl.gif" width="120" height="22" /> <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="1" height="1" id="flash" align="middle"> <param name="allowScriptAccess" value="sameDomain"/> <param name="movie" value="/per/bharosa_web/flash/bharosa.swf"/> <param name="quality" value="low"/> <param name="bgcolor" value="#ffffff"/> <param name=FlashVars value="dcUrl=/dc?s=true&"/> <embed src="/per/bharosa_web/flash/bharosa.swf" quality="low" bgcolor="#ffffff" FlashVars="dcUrl=/dc?s=true&" width="1" height="1"name="flash" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash"/> </object> </td></tr> <tr><td height="35" align="center"> </td></tr> <tr><td align="left"> <table cellpadding="0" cellspacing="3" border="0" width="100%"> <tr> <td class="size01 txt02" align="right" width="120">登录名或账号:&nbsp;&nbsp;</td> <td align="left" height="32" width="190"><input name="LoginName" id="skey" value="" class="input_out3" onfocus="this.className='input_on3';this.onmouseout=''" onblur="this.className='input_off3';this.onmouseout=function(){this.className='input_out3'};" type="text" size="16" /></td> <td width="100">&nbsp;</td> </tr> <tr> <td class="size01 txt02" align="right" width="120">登录密码:<img src="images/public/wen.gif" alt="请输入您设置的8~14位网银登录密码"/></td> <td align="left" height="32"> <script type="text/javascript">writePassObject("powerpassword",{"fieldName":"Password","maxLength":"20","minLength":"0","width":"186px","height":"23px","msgBox":"false","maskChar":"*","borderColor":"#7f9db9"});</script> </td> <td align="left"> <a href="####" class="txt_line txt07" onclick="MM_openBrWindow('pwdHelp.do','个人网上银行常见问题解答','width=640,height=420')">密码输入帮助</a> <img id="image1" src="tokenImage.xx?_timesShowToken=2&ran=063319703" style="display:none"/> </td> </tr> <tr><td colspan="3" height="10"></td></tr> <tr><td colspan="3" align="center"> <img src="images/public/denglu_1.gif" onclick="doLogin();" style="cursor: hand"/>&nbsp;&nbsp;&nbsp;&nbsp; </td></tr> </table> </td></tr> <tr><td height="23"></td></tr> <tr><td class="txt08" align="center"><a href="FP320501.do" class="txt07 txt_line">找回登录名</a> | <a href="FP320301.do" class="txt07 txt_line">忘记登录密码</a> | <a href="FP990101.do?ident=gr&idper=ds" class="txt07 txt_line">我要开通网银</a> </td></tr> </table> <!--登录区结束--> </td> </tr> </table> </form> </source> == Sample Form == * username = 11111111 * password = 22222222 <source lang="xml"> <entry method="POST" url="https://www.cebbank.com/per/perlogin1.do"> <timestart>2014-06-19T06:00:43.594Z</timestart> <timeend>2014-06-19T06:00:44.064Z</timeend> <duration>0.470 s</duration> <processname>C:\Program Files\Internet Explorer\iexplore.exe</processname> <result>200 OK</result> <size>0</size> <stage>REQUEST_CLOSE</stage> <mimetype>text/html</mimetype> <redirecturl/> <requestCamefromCache>False</requestCamefromCache> <responseCamefromCache>False</responseCamefromCache> <requestobjectname>/per/perlogin1.do</requestobjectname> <winet_sr_result>True</winet_sr_result> <winet_sr_errormessage/> <bodySize>9333</bodySize> <Web_PageID>0</Web_PageID> <PageTitle/> <Socket_SendSize>0</Socket_SendSize> <Socket_RecvSize>0</Socket_RecvSize> <Starred>False</Starred> <Comment/> <headers> <requestheaders> <header>POST /per/perlogin1.do HTTP/1.1</header> <header>Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, */*</header> <header>Referer: https://www.cebbank.com/per/prePerlogin.do?_locale=zh_CN</header> <header>Accept-Language: en-us</header> <header>User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)</header> <header>Content-Type: application/x-www-form-urlencoded</header> <header>Accept-Encoding: gzip, deflate</header> <header>Host: www.cebbank.com</header> <header>Connection: Keep-Alive</header> <header>Cache-Control: no-cache</header> <header>Cookie: WT_FPC=id=2b3fd12fcdda9131eb91403212946597:lv=1403212951284:ss=1403212946597; cebmemberbranchcode=3550; cebmemberbranchname=%u5317%u4EAC%u5206%u884C; PERJSESSIONID=t6m9Tv0cW5s9jN7JhXFLBhvsbwnG9h4gLn0pyqKgDp97tnNPxdpC!-2124310495; BIGipServerpool_eb_8005=2366482624.17695.0000</header> <header>Content-Length: 388</header> </requestheaders> <responseheaders> <header>HTTP/1.1 200 OK</header> <header>Server: Sun-Java-System-Web-Server/7.0</header> <header>Date: Thu, 19 Jun 2014 10:01:06 GMT</header> <header>Cache-Control: no-cache</header> <header>Date: Thu, 19 Jun 2014 09:59:58 GMT</header> <header>Pragma: No-cache</header> <header>Content-type: text/html; charset=gbk</header> <header>Expires: Thu, 01 Jan 1970 00:00:00 GMT</header> <header>Content-Language: zh-CN</header> <header>X-Powered-By: Servlet/2.5 JSP/2.1</header> <header>Connection: Keep-alive</header> <header>Via: 1.1 AN-0001544151441131</header> <header>Content-Length: 9333</header> </responseheaders> </headers> <content> <contentLength>9333</contentLength> <mimetype>text/html</mimetype> </content> <cookies> <sent> <cookie name=" WT_FPC">id=2b3fd12fcdda9131eb91403212946597:lv=1403212951284:ss=1403212946597</cookie> <cookie name=" cebmemberbranchcode">3550</cookie> <cookie name=" cebmemberbranchname">&#177;&#177;&#190;&#169;&#183;&#214;&#208;&#208;</cookie> <cookie name=" PERJSESSIONID">t6m9Tv0cW5s9jN7JhXFLBhvsbwnG9h4gLn0pyqKgDp97tnNPxdpC!-2124310495</cookie> <cookie name=" BIGipServerpool_eb_8005">2366482624.17695.0000</cookie> </sent> <received/> </cookies> <cache> <BeforeRequest> <UrlInCache>False</UrlInCache> </BeforeRequest> <AfterRequest> <UrlInCache>False</UrlInCache> </AfterRequest> </cache> <QueryString/> <PostData> <mimetype>application/x-www-form-urlencoded</mimetype> <size>388</size> <params> <param name="_viewReferer">login/login01</param> <param name="_locale">zh_CN</param> <param name="version">20140529</param> <param name="Password">XQn0aqYKjJeFutYuXaooFuDF7cAU7jAYd4lpIff/qaZOd1gElxbw/ChRmY1mipjeUlpO0lO8FHO13VaeEyaQf54np25wFo6X2t0LlAKKpruupbDHEWas3pVuajAXsuUqsyqSeDqNlsXpckRWdFBopnzoKuggcgkaMLXsyJtGLU8=</param> <param name="ran">55924190</param> <param name="TransName"/> <param name="Plain"/> <param name="Signature"/> <param name="MerName"/> <param name="TransType"/> <param name="OperationNo"/> <param name="MerDCFlag"/> <param name="checkloginflag"/> <param name="_tokenName">z90qww5h</param> <param name="LoginName">11111111</param> </params> </entry> </source> == API Calls == 6f78fd67c4cefb1134ebd96df95c885af7d8a9af 372 371 2014-06-19T13:03:15Z HenryHu 1 /* API Calls */ wikitext text/x-wiki == Objects == * cebiesign <pre> <object id="cebiesign" name="cebiesign" classid="clsid:f3e92562-1b4d-4bfa-b2d4-e9bcabe3b5a8" codebase="js/cebiesign.ocx#version=2,0,0,4" border="0"> </object> </pre> * powercommit <pre> <object id="powercommit" codebase="js/PowerEnter.CAB#version=1,0,0,72" classid="clsid:BEEE2807-1709-4184-A05D-1B2DE01EE4CF" style="width:0px;height:0px" height="0" width="0"> <param name="width" value="0"> <param name="height" value="0"> <param name="frameName" value="mainFrame"> </object> </pre> * powerpassword <pre> <object id="powerpassword" codebase="js/PowerEnter.CAB#version=1,0,0,72" classid="clsid:614E58F9-74D0-4D7B-90E3-64A0F2AA73B4" style="width:186pxpx;height:23pxpx" height="23px" width="186px"> <param name="width" value="186px"> <param name="height" value="23px"> <param name="maxLength" value="20"> <param name="minLength" value="0"> <param name="maskChar" value="*"> <param name="backColor" value="#FFFFFF"> <param name="textColor" value="#000000"> <param name="borderColor" value="#7f9db9"> <param name="accepts" value="*"> <param name="msgBox" value="false"> <param name="fieldName" value="Password"> </object> </pre> == Commit Code == <source lang="javascript"> var blob ="BgIAAACkAABSU0ExAAQAAAEAAQAfFsbhRXwKJMLpsGExRSNaUxLZhaHvMp9ZJEgO2sa30lj6jc2BkNrF/35TKQuLphYVYwDLADdbRj23ChSzVWVmQwAs9CXrqR3tcYavKGsRBEeHEFctULIt6QFn/1Gz6F11k61K8G9yMXy9AGgN+pHum2X3EODpRJBFH9/w1VC+1w=="; function doLogin() { var ran = "<random value>"; if(ran != null && ran !="") { var random = parseFloat(ran)+1; document.form1.ran.value = random; } else { document.form1.ran.value = 0; } var powercommit = document.getElementById("powercommit"); var powerpassword = document.getElementById("powerpassword"); powercommit.reset(); powerpassword.publicKeyBlob(blob); powerpassword.commit("powercommit"); powercommit.submit("form1"); } </source> == Form Params == <source lang="html5"> <form name="form1" action="perlogin1.do" method="post"> <input type="hidden" name="_viewReferer" value="login/login01" /> <input type="hidden" name="_locale" value="zh_CN" /> <input type="hidden" name="version" value="20140529" /> <input type="hidden" name="Password" /> <input type="hidden" name="ran" value="063319703" /> <input type="hidden" name="TransName" value="" /> <input type="hidden" name="Plain" value="" /> <input type="hidden" name="Signature" value="" /> <input type="hidden" name="MerName" value="" /> <input type="hidden" name="TransType" value="" /> <input type="hidden" name="OperationNo" value="" /> <input type="hidden" name="MerDCFlag" value="" /> <input type="hidden" name="checkloginflag" value="" /> <input type="hidden" name="_tokenName" value="1jjihb5u" /> <div class="box"> <!--头部--> <div class=" head"><table cellpadding="0" cellspacing="0" border="0" style="margin:10px 0;"><tr><td align="left" ><img src="images/public/login_2.gif" /></td> </tr> </table> </div> <!--头部结束--> <!--内容--> <div class="content"> <table cellpadding="0" cellspacing="0" border="0"> <tr> <td class="conback" valign="top" > </td> <td class="conback2" valign="top" align="center"> <!--登录区--> <table cellpadding="0" cellspacing="0" border="0" class="login" width="433"> <tr><td valign="top" class="title line01" align="left"><img src="images/public/yhdl.gif" width="120" height="22" /> <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="1" height="1" id="flash" align="middle"> <param name="allowScriptAccess" value="sameDomain"/> <param name="movie" value="/per/bharosa_web/flash/bharosa.swf"/> <param name="quality" value="low"/> <param name="bgcolor" value="#ffffff"/> <param name=FlashVars value="dcUrl=/dc?s=true&"/> <embed src="/per/bharosa_web/flash/bharosa.swf" quality="low" bgcolor="#ffffff" FlashVars="dcUrl=/dc?s=true&" width="1" height="1"name="flash" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash"/> </object> </td></tr> <tr><td height="35" align="center"> </td></tr> <tr><td align="left"> <table cellpadding="0" cellspacing="3" border="0" width="100%"> <tr> <td class="size01 txt02" align="right" width="120">登录名或账号:&nbsp;&nbsp;</td> <td align="left" height="32" width="190"><input name="LoginName" id="skey" value="" class="input_out3" onfocus="this.className='input_on3';this.onmouseout=''" onblur="this.className='input_off3';this.onmouseout=function(){this.className='input_out3'};" type="text" size="16" /></td> <td width="100">&nbsp;</td> </tr> <tr> <td class="size01 txt02" align="right" width="120">登录密码:<img src="images/public/wen.gif" alt="请输入您设置的8~14位网银登录密码"/></td> <td align="left" height="32"> <script type="text/javascript">writePassObject("powerpassword",{"fieldName":"Password","maxLength":"20","minLength":"0","width":"186px","height":"23px","msgBox":"false","maskChar":"*","borderColor":"#7f9db9"});</script> </td> <td align="left"> <a href="####" class="txt_line txt07" onclick="MM_openBrWindow('pwdHelp.do','个人网上银行常见问题解答','width=640,height=420')">密码输入帮助</a> <img id="image1" src="tokenImage.xx?_timesShowToken=2&ran=063319703" style="display:none"/> </td> </tr> <tr><td colspan="3" height="10"></td></tr> <tr><td colspan="3" align="center"> <img src="images/public/denglu_1.gif" onclick="doLogin();" style="cursor: hand"/>&nbsp;&nbsp;&nbsp;&nbsp; </td></tr> </table> </td></tr> <tr><td height="23"></td></tr> <tr><td class="txt08" align="center"><a href="FP320501.do" class="txt07 txt_line">找回登录名</a> | <a href="FP320301.do" class="txt07 txt_line">忘记登录密码</a> | <a href="FP990101.do?ident=gr&idper=ds" class="txt07 txt_line">我要开通网银</a> </td></tr> </table> <!--登录区结束--> </td> </tr> </table> </form> </source> == Sample Form == * username = 11111111 * password = 22222222 <source lang="xml"> <entry method="POST" url="https://www.cebbank.com/per/perlogin1.do"> <timestart>2014-06-19T06:00:43.594Z</timestart> <timeend>2014-06-19T06:00:44.064Z</timeend> <duration>0.470 s</duration> <processname>C:\Program Files\Internet Explorer\iexplore.exe</processname> <result>200 OK</result> <size>0</size> <stage>REQUEST_CLOSE</stage> <mimetype>text/html</mimetype> <redirecturl/> <requestCamefromCache>False</requestCamefromCache> <responseCamefromCache>False</responseCamefromCache> <requestobjectname>/per/perlogin1.do</requestobjectname> <winet_sr_result>True</winet_sr_result> <winet_sr_errormessage/> <bodySize>9333</bodySize> <Web_PageID>0</Web_PageID> <PageTitle/> <Socket_SendSize>0</Socket_SendSize> <Socket_RecvSize>0</Socket_RecvSize> <Starred>False</Starred> <Comment/> <headers> <requestheaders> <header>POST /per/perlogin1.do HTTP/1.1</header> <header>Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, */*</header> <header>Referer: https://www.cebbank.com/per/prePerlogin.do?_locale=zh_CN</header> <header>Accept-Language: en-us</header> <header>User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)</header> <header>Content-Type: application/x-www-form-urlencoded</header> <header>Accept-Encoding: gzip, deflate</header> <header>Host: www.cebbank.com</header> <header>Connection: Keep-Alive</header> <header>Cache-Control: no-cache</header> <header>Cookie: WT_FPC=id=2b3fd12fcdda9131eb91403212946597:lv=1403212951284:ss=1403212946597; cebmemberbranchcode=3550; cebmemberbranchname=%u5317%u4EAC%u5206%u884C; PERJSESSIONID=t6m9Tv0cW5s9jN7JhXFLBhvsbwnG9h4gLn0pyqKgDp97tnNPxdpC!-2124310495; BIGipServerpool_eb_8005=2366482624.17695.0000</header> <header>Content-Length: 388</header> </requestheaders> <responseheaders> <header>HTTP/1.1 200 OK</header> <header>Server: Sun-Java-System-Web-Server/7.0</header> <header>Date: Thu, 19 Jun 2014 10:01:06 GMT</header> <header>Cache-Control: no-cache</header> <header>Date: Thu, 19 Jun 2014 09:59:58 GMT</header> <header>Pragma: No-cache</header> <header>Content-type: text/html; charset=gbk</header> <header>Expires: Thu, 01 Jan 1970 00:00:00 GMT</header> <header>Content-Language: zh-CN</header> <header>X-Powered-By: Servlet/2.5 JSP/2.1</header> <header>Connection: Keep-alive</header> <header>Via: 1.1 AN-0001544151441131</header> <header>Content-Length: 9333</header> </responseheaders> </headers> <content> <contentLength>9333</contentLength> <mimetype>text/html</mimetype> </content> <cookies> <sent> <cookie name=" WT_FPC">id=2b3fd12fcdda9131eb91403212946597:lv=1403212951284:ss=1403212946597</cookie> <cookie name=" cebmemberbranchcode">3550</cookie> <cookie name=" cebmemberbranchname">&#177;&#177;&#190;&#169;&#183;&#214;&#208;&#208;</cookie> <cookie name=" PERJSESSIONID">t6m9Tv0cW5s9jN7JhXFLBhvsbwnG9h4gLn0pyqKgDp97tnNPxdpC!-2124310495</cookie> <cookie name=" BIGipServerpool_eb_8005">2366482624.17695.0000</cookie> </sent> <received/> </cookies> <cache> <BeforeRequest> <UrlInCache>False</UrlInCache> </BeforeRequest> <AfterRequest> <UrlInCache>False</UrlInCache> </AfterRequest> </cache> <QueryString/> <PostData> <mimetype>application/x-www-form-urlencoded</mimetype> <size>388</size> <params> <param name="_viewReferer">login/login01</param> <param name="_locale">zh_CN</param> <param name="version">20140529</param> <param name="Password">XQn0aqYKjJeFutYuXaooFuDF7cAU7jAYd4lpIff/qaZOd1gElxbw/ChRmY1mipjeUlpO0lO8FHO13VaeEyaQf54np25wFo6X2t0LlAKKpruupbDHEWas3pVuajAXsuUqsyqSeDqNlsXpckRWdFBopnzoKuggcgkaMLXsyJtGLU8=</param> <param name="ran">55924190</param> <param name="TransName"/> <param name="Plain"/> <param name="Signature"/> <param name="MerName"/> <param name="TransType"/> <param name="OperationNo"/> <param name="MerDCFlag"/> <param name="checkloginflag"/> <param name="_tokenName">z90qww5h</param> <param name="LoginName">11111111</param> </params> </entry> </source> == API Calls == CryptImportKey(blob) CryptEncrypt(NULL, 8) -> 128 (128 bytes required) CryptEncrypt(password, 8) -> encrypted pw encrypted pw: 0x03310BD0 D3 5F 47 03 22 A3 0D FA 0C DC 3D BE 06 43 E8 06 ._G.".....=..C.. 0x03310BE0 AF 4D E3 85 80 04 6F 38 46 80 AC F7 E5 79 23 6C .M....o8F....y#l 0x03310BF0 87 E0 D9 81 2B E7 EC 2B AE B7 BB 19 9B A4 13 68 ....+..+.......h 0x03310C00 E9 2B B3 64 80 DE E4 66 66 10 BF D5 56 2A 4E BC .+.d...ff...V*N. 0x03310C10 56 E4 47 66 7E 16 D7 DB 66 B7 05 43 BC AF D6 95 V.Gf~...f..C.... 0x03310C20 AA AD 37 31 0D DE E7 37 7E 71 D2 43 CE 65 1B EB ..71...7~q.C.e.. 0x03310C30 A4 03 03 D7 77 C7 7B A7 41 EA 51 B4 65 70 AD 08 ....w.{.A.Q.ep.. 0x03310C40 63 B3 63 21 84 05 37 F8 6D 2E 74 3C 1A 6A E0 C8 c.c!..7.m.t<.j.. 0x03332BA0 EC 3D A5 ED 3E B1 D7 59 60 9D 36 BA AC CB 22 EA .=..>..Y`.6...". 0x03332BB0 87 15 9A BB 73 D4 39 82 DB 07 3D 66 E7 28 E5 BF ....s.9...=f.(.. 0x03332BC0 6B 2E 0F C9 5E 23 9D 34 DC D2 D7 F3 99 20 A5 1E k...^#.4..... .. 0x03332BD0 56 41 97 F9 38 94 60 A4 7B 36 90 CF 78 99 EA 87 VA..8.`.{6..x... 0x03332BE0 4F 7E 3E 61 68 D8 C4 8E FD ED D3 DF FD 82 38 A1 O~>ah.........8. 0x03332BF0 0B 18 29 14 41 D6 FC C5 3C 3B 6A D1 61 97 17 57 ..).A...<;j.a..W 0x03332C00 E2 D2 F9 0E 11 57 4A AB 16 60 0F 3C 2D 4F DD 07 .....WJ..`.<-O.. 0x03332C10 2B 57 5A 49 3C D2 F4 DF F8 A0 E1 2D 4A DB BF 25 +WZI<......-J..% CryptCreateHash() CryptHashData(key1, 21) key1: 0x035092F8 63 73 69 69 5F 70 6F 77 65 72 65 6E 74 65 72 5F csii_powerenter_ 0x03509308 6A 61 73 6F 6E jason CryptEncrypt(key2, 16) -> encrypted key2 key2: 0x009AAC78 79 4B 52 6E 49 4E 7A 76 72 65 39 72 65 51 3D 3D yKRnINzvre9reQ== 0x0330FD70 30 66 6B 2B 63 39 7A 47 37 50 5A 48 59 41 3D 3D 0fk+c9zG7PZHYA== decoded key2: 00000000 c8 a4 67 20 dc ef ad ef 6b 79 |..g ....ky| 00000000 d1 f9 3e 73 dc c6 ec f6 47 60 |..>s....G`| encrypted key2: 0x009AAC78 D2 5B D6 88 DA F1 04 C6 97 0B 46 48 5F 07 84 D6 .[........FH_... 0x0330FD70 9B 76 EF CD F0 86 04 F7 D2 3E 25 72 63 17 84 D6 .v.......>%rc... CryptHashData(key1, 21) submit pw: Jb/bSi3hoPjf9NI8SVpXKwfdTy08D2AWq0pXEQ750uJXF5dh0Wo7PMX81kEUKRgLoTiC/d/T7f2OxNhoYT5+T4fqmXjPkDZ7pGCUOPmXQVYepSCZ89fS3DSdI17JDy5rv+Uo52Y9B9uCOdRzu5oVh+oiy6y6Np1gWdexPu2lPew= ran: 75915681 token: k1ssjcn1 c5772f6ed1be29c698f568eefd4c3aa9e304061b 373 372 2014-06-19T14:48:33Z HenryHu 1 /* API Calls */ wikitext text/x-wiki == Objects == * cebiesign <pre> <object id="cebiesign" name="cebiesign" classid="clsid:f3e92562-1b4d-4bfa-b2d4-e9bcabe3b5a8" codebase="js/cebiesign.ocx#version=2,0,0,4" border="0"> </object> </pre> * powercommit <pre> <object id="powercommit" codebase="js/PowerEnter.CAB#version=1,0,0,72" classid="clsid:BEEE2807-1709-4184-A05D-1B2DE01EE4CF" style="width:0px;height:0px" height="0" width="0"> <param name="width" value="0"> <param name="height" value="0"> <param name="frameName" value="mainFrame"> </object> </pre> * powerpassword <pre> <object id="powerpassword" codebase="js/PowerEnter.CAB#version=1,0,0,72" classid="clsid:614E58F9-74D0-4D7B-90E3-64A0F2AA73B4" style="width:186pxpx;height:23pxpx" height="23px" width="186px"> <param name="width" value="186px"> <param name="height" value="23px"> <param name="maxLength" value="20"> <param name="minLength" value="0"> <param name="maskChar" value="*"> <param name="backColor" value="#FFFFFF"> <param name="textColor" value="#000000"> <param name="borderColor" value="#7f9db9"> <param name="accepts" value="*"> <param name="msgBox" value="false"> <param name="fieldName" value="Password"> </object> </pre> == Commit Code == <source lang="javascript"> var blob ="BgIAAACkAABSU0ExAAQAAAEAAQAfFsbhRXwKJMLpsGExRSNaUxLZhaHvMp9ZJEgO2sa30lj6jc2BkNrF/35TKQuLphYVYwDLADdbRj23ChSzVWVmQwAs9CXrqR3tcYavKGsRBEeHEFctULIt6QFn/1Gz6F11k61K8G9yMXy9AGgN+pHum2X3EODpRJBFH9/w1VC+1w=="; function doLogin() { var ran = "<random value>"; if(ran != null && ran !="") { var random = parseFloat(ran)+1; document.form1.ran.value = random; } else { document.form1.ran.value = 0; } var powercommit = document.getElementById("powercommit"); var powerpassword = document.getElementById("powerpassword"); powercommit.reset(); powerpassword.publicKeyBlob(blob); powerpassword.commit("powercommit"); powercommit.submit("form1"); } </source> == Form Params == <source lang="html5"> <form name="form1" action="perlogin1.do" method="post"> <input type="hidden" name="_viewReferer" value="login/login01" /> <input type="hidden" name="_locale" value="zh_CN" /> <input type="hidden" name="version" value="20140529" /> <input type="hidden" name="Password" /> <input type="hidden" name="ran" value="063319703" /> <input type="hidden" name="TransName" value="" /> <input type="hidden" name="Plain" value="" /> <input type="hidden" name="Signature" value="" /> <input type="hidden" name="MerName" value="" /> <input type="hidden" name="TransType" value="" /> <input type="hidden" name="OperationNo" value="" /> <input type="hidden" name="MerDCFlag" value="" /> <input type="hidden" name="checkloginflag" value="" /> <input type="hidden" name="_tokenName" value="1jjihb5u" /> <div class="box"> <!--头部--> <div class=" head"><table cellpadding="0" cellspacing="0" border="0" style="margin:10px 0;"><tr><td align="left" ><img src="images/public/login_2.gif" /></td> </tr> </table> </div> <!--头部结束--> <!--内容--> <div class="content"> <table cellpadding="0" cellspacing="0" border="0"> <tr> <td class="conback" valign="top" > </td> <td class="conback2" valign="top" align="center"> <!--登录区--> <table cellpadding="0" cellspacing="0" border="0" class="login" width="433"> <tr><td valign="top" class="title line01" align="left"><img src="images/public/yhdl.gif" width="120" height="22" /> <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="1" height="1" id="flash" align="middle"> <param name="allowScriptAccess" value="sameDomain"/> <param name="movie" value="/per/bharosa_web/flash/bharosa.swf"/> <param name="quality" value="low"/> <param name="bgcolor" value="#ffffff"/> <param name=FlashVars value="dcUrl=/dc?s=true&"/> <embed src="/per/bharosa_web/flash/bharosa.swf" quality="low" bgcolor="#ffffff" FlashVars="dcUrl=/dc?s=true&" width="1" height="1"name="flash" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash"/> </object> </td></tr> <tr><td height="35" align="center"> </td></tr> <tr><td align="left"> <table cellpadding="0" cellspacing="3" border="0" width="100%"> <tr> <td class="size01 txt02" align="right" width="120">登录名或账号:&nbsp;&nbsp;</td> <td align="left" height="32" width="190"><input name="LoginName" id="skey" value="" class="input_out3" onfocus="this.className='input_on3';this.onmouseout=''" onblur="this.className='input_off3';this.onmouseout=function(){this.className='input_out3'};" type="text" size="16" /></td> <td width="100">&nbsp;</td> </tr> <tr> <td class="size01 txt02" align="right" width="120">登录密码:<img src="images/public/wen.gif" alt="请输入您设置的8~14位网银登录密码"/></td> <td align="left" height="32"> <script type="text/javascript">writePassObject("powerpassword",{"fieldName":"Password","maxLength":"20","minLength":"0","width":"186px","height":"23px","msgBox":"false","maskChar":"*","borderColor":"#7f9db9"});</script> </td> <td align="left"> <a href="####" class="txt_line txt07" onclick="MM_openBrWindow('pwdHelp.do','个人网上银行常见问题解答','width=640,height=420')">密码输入帮助</a> <img id="image1" src="tokenImage.xx?_timesShowToken=2&ran=063319703" style="display:none"/> </td> </tr> <tr><td colspan="3" height="10"></td></tr> <tr><td colspan="3" align="center"> <img src="images/public/denglu_1.gif" onclick="doLogin();" style="cursor: hand"/>&nbsp;&nbsp;&nbsp;&nbsp; </td></tr> </table> </td></tr> <tr><td height="23"></td></tr> <tr><td class="txt08" align="center"><a href="FP320501.do" class="txt07 txt_line">找回登录名</a> | <a href="FP320301.do" class="txt07 txt_line">忘记登录密码</a> | <a href="FP990101.do?ident=gr&idper=ds" class="txt07 txt_line">我要开通网银</a> </td></tr> </table> <!--登录区结束--> </td> </tr> </table> </form> </source> == Sample Form == * username = 11111111 * password = 22222222 <source lang="xml"> <entry method="POST" url="https://www.cebbank.com/per/perlogin1.do"> <timestart>2014-06-19T06:00:43.594Z</timestart> <timeend>2014-06-19T06:00:44.064Z</timeend> <duration>0.470 s</duration> <processname>C:\Program Files\Internet Explorer\iexplore.exe</processname> <result>200 OK</result> <size>0</size> <stage>REQUEST_CLOSE</stage> <mimetype>text/html</mimetype> <redirecturl/> <requestCamefromCache>False</requestCamefromCache> <responseCamefromCache>False</responseCamefromCache> <requestobjectname>/per/perlogin1.do</requestobjectname> <winet_sr_result>True</winet_sr_result> <winet_sr_errormessage/> <bodySize>9333</bodySize> <Web_PageID>0</Web_PageID> <PageTitle/> <Socket_SendSize>0</Socket_SendSize> <Socket_RecvSize>0</Socket_RecvSize> <Starred>False</Starred> <Comment/> <headers> <requestheaders> <header>POST /per/perlogin1.do HTTP/1.1</header> <header>Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, */*</header> <header>Referer: https://www.cebbank.com/per/prePerlogin.do?_locale=zh_CN</header> <header>Accept-Language: en-us</header> <header>User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)</header> <header>Content-Type: application/x-www-form-urlencoded</header> <header>Accept-Encoding: gzip, deflate</header> <header>Host: www.cebbank.com</header> <header>Connection: Keep-Alive</header> <header>Cache-Control: no-cache</header> <header>Cookie: WT_FPC=id=2b3fd12fcdda9131eb91403212946597:lv=1403212951284:ss=1403212946597; cebmemberbranchcode=3550; cebmemberbranchname=%u5317%u4EAC%u5206%u884C; PERJSESSIONID=t6m9Tv0cW5s9jN7JhXFLBhvsbwnG9h4gLn0pyqKgDp97tnNPxdpC!-2124310495; BIGipServerpool_eb_8005=2366482624.17695.0000</header> <header>Content-Length: 388</header> </requestheaders> <responseheaders> <header>HTTP/1.1 200 OK</header> <header>Server: Sun-Java-System-Web-Server/7.0</header> <header>Date: Thu, 19 Jun 2014 10:01:06 GMT</header> <header>Cache-Control: no-cache</header> <header>Date: Thu, 19 Jun 2014 09:59:58 GMT</header> <header>Pragma: No-cache</header> <header>Content-type: text/html; charset=gbk</header> <header>Expires: Thu, 01 Jan 1970 00:00:00 GMT</header> <header>Content-Language: zh-CN</header> <header>X-Powered-By: Servlet/2.5 JSP/2.1</header> <header>Connection: Keep-alive</header> <header>Via: 1.1 AN-0001544151441131</header> <header>Content-Length: 9333</header> </responseheaders> </headers> <content> <contentLength>9333</contentLength> <mimetype>text/html</mimetype> </content> <cookies> <sent> <cookie name=" WT_FPC">id=2b3fd12fcdda9131eb91403212946597:lv=1403212951284:ss=1403212946597</cookie> <cookie name=" cebmemberbranchcode">3550</cookie> <cookie name=" cebmemberbranchname">&#177;&#177;&#190;&#169;&#183;&#214;&#208;&#208;</cookie> <cookie name=" PERJSESSIONID">t6m9Tv0cW5s9jN7JhXFLBhvsbwnG9h4gLn0pyqKgDp97tnNPxdpC!-2124310495</cookie> <cookie name=" BIGipServerpool_eb_8005">2366482624.17695.0000</cookie> </sent> <received/> </cookies> <cache> <BeforeRequest> <UrlInCache>False</UrlInCache> </BeforeRequest> <AfterRequest> <UrlInCache>False</UrlInCache> </AfterRequest> </cache> <QueryString/> <PostData> <mimetype>application/x-www-form-urlencoded</mimetype> <size>388</size> <params> <param name="_viewReferer">login/login01</param> <param name="_locale">zh_CN</param> <param name="version">20140529</param> <param name="Password">XQn0aqYKjJeFutYuXaooFuDF7cAU7jAYd4lpIff/qaZOd1gElxbw/ChRmY1mipjeUlpO0lO8FHO13VaeEyaQf54np25wFo6X2t0LlAKKpruupbDHEWas3pVuajAXsuUqsyqSeDqNlsXpckRWdFBopnzoKuggcgkaMLXsyJtGLU8=</param> <param name="ran">55924190</param> <param name="TransName"/> <param name="Plain"/> <param name="Signature"/> <param name="MerName"/> <param name="TransType"/> <param name="OperationNo"/> <param name="MerDCFlag"/> <param name="checkloginflag"/> <param name="_tokenName">z90qww5h</param> <param name="LoginName">11111111</param> </params> </entry> </source> == API Calls == <pre> CryptImportKey(blob) CryptEncrypt(NULL, 8) -> 128 (128 bytes required) CryptEncrypt(password, 8) -> encrypted pw encrypted pw: 0x03310BD0 D3 5F 47 03 22 A3 0D FA 0C DC 3D BE 06 43 E8 06 ._G.".....=..C.. 0x03310BE0 AF 4D E3 85 80 04 6F 38 46 80 AC F7 E5 79 23 6C .M....o8F....y#l 0x03310BF0 87 E0 D9 81 2B E7 EC 2B AE B7 BB 19 9B A4 13 68 ....+..+.......h 0x03310C00 E9 2B B3 64 80 DE E4 66 66 10 BF D5 56 2A 4E BC .+.d...ff...V*N. 0x03310C10 56 E4 47 66 7E 16 D7 DB 66 B7 05 43 BC AF D6 95 V.Gf~...f..C.... 0x03310C20 AA AD 37 31 0D DE E7 37 7E 71 D2 43 CE 65 1B EB ..71...7~q.C.e.. 0x03310C30 A4 03 03 D7 77 C7 7B A7 41 EA 51 B4 65 70 AD 08 ....w.{.A.Q.ep.. 0x03310C40 63 B3 63 21 84 05 37 F8 6D 2E 74 3C 1A 6A E0 C8 c.c!..7.m.t<.j.. 0x03332BA0 EC 3D A5 ED 3E B1 D7 59 60 9D 36 BA AC CB 22 EA .=..>..Y`.6...". 0x03332BB0 87 15 9A BB 73 D4 39 82 DB 07 3D 66 E7 28 E5 BF ....s.9...=f.(.. 0x03332BC0 6B 2E 0F C9 5E 23 9D 34 DC D2 D7 F3 99 20 A5 1E k...^#.4..... .. 0x03332BD0 56 41 97 F9 38 94 60 A4 7B 36 90 CF 78 99 EA 87 VA..8.`.{6..x... 0x03332BE0 4F 7E 3E 61 68 D8 C4 8E FD ED D3 DF FD 82 38 A1 O~>ah.........8. 0x03332BF0 0B 18 29 14 41 D6 FC C5 3C 3B 6A D1 61 97 17 57 ..).A...<;j.a..W 0x03332C00 E2 D2 F9 0E 11 57 4A AB 16 60 0F 3C 2D 4F DD 07 .....WJ..`.<-O.. 0x03332C10 2B 57 5A 49 3C D2 F4 DF F8 A0 E1 2D 4A DB BF 25 +WZI<......-J..% CryptGenRandom(10) -> random random: 00000000 c8 a4 67 20 dc ef ad ef 6b 79 |..g ....ky| 00000000 d1 f9 3e 73 dc c6 ec f6 47 60 |..>s....G`| CryptCreateHash(MD5) CryptHashData(key1, 21) key1: "csii_powerenter_jason" 0x035092F8 63 73 69 69 5F 70 6F 77 65 72 65 6E 74 65 72 5F csii_powerenter_ 0x03509308 6A 61 73 6F 6E jason CryptDeriveKey() -> dkey1 CryptEncrypt(dkey1, key2, 16) -> encrypted key2 key2: = base64(random) 0x009AAC78 79 4B 52 6E 49 4E 7A 76 72 65 39 72 65 51 3D 3D yKRnINzvre9reQ== 0x0330FD70 30 66 6B 2B 63 39 7A 47 37 50 5A 48 59 41 3D 3D 0fk+c9zG7PZHYA== encrypted key2: 0x009AAC78 D2 5B D6 88 DA F1 04 C6 97 0B 46 48 5F 07 84 D6 .[........FH_... 0x0330FD70 9B 76 EF CD F0 86 04 F7 D2 3E 25 72 63 17 84 D6 .v.......>%rc... CryptHashData(key1, 21) submit pw: Jb/bSi3hoPjf9NI8SVpXKwfdTy08D2AWq0pXEQ750uJXF5dh0Wo7PMX81kEUKRgLoTiC/d/T7f2OxNhoYT5+T4fqmXjPkDZ7pGCUOPmXQVYepSCZ89fS3DSdI17JDy5rv+Uo52Y9B9uCOdRzu5oVh+oiy6y6Np1gWdexPu2lPew= 00000000 25 bf db 4a 2d e1 a0 f8 df f4 d2 3c 49 5a 57 2b |%..J-......<IZW+| 00000010 07 dd 4f 2d 3c 0f 60 16 ab 4a 57 11 0e f9 d2 e2 |..O-<.`..JW.....| 00000020 57 17 97 61 d1 6a 3b 3c c5 fc d6 41 14 29 18 0b |W..a.j;<...A.)..| 00000030 a1 38 82 fd df d3 ed fd 8e c4 d8 68 61 3e 7e 4f |.8.........ha>~O| 00000040 87 ea 99 78 cf 90 36 7b a4 60 94 38 f9 97 41 56 |...x..6{.`.8..AV| 00000050 1e a5 20 99 f3 d7 d2 dc 34 9d 23 5e c9 0f 2e 6b |.. .....4.#^...k| 00000060 bf e5 28 e7 66 3d 07 db 82 39 d4 73 bb 9a 15 87 |..(.f=...9.s....| 00000070 ea 22 cb ac ba 36 9d 60 59 d7 b1 3e ed a5 3d ec |."...6.`Y..>..=.| 00000080 ran: 75915681 token: k1ssjcn1 CryptDecrypt(0x2e86470, sth, 16) -> decrypted sth sth: 0x03309EC8 EE 42 D4 D1 D5 C5 4D DC 91 3E 4E 70 58 31 84 D6 .B....M..>NpX1.. decrypted sth: = base64(random) = key2 0x03309EC8 45 52 50 37 46 7A 33 6C 74 50 31 4A 62 67 3D 3D ERP7Fz3ltP1Jbg== </pre> 511a06b0f68d038f2fdc5eeddf5a3903fece3c23 374 373 2014-06-20T08:59:44Z HenryHu 1 /* API Calls */ wikitext text/x-wiki == Objects == * cebiesign <pre> <object id="cebiesign" name="cebiesign" classid="clsid:f3e92562-1b4d-4bfa-b2d4-e9bcabe3b5a8" codebase="js/cebiesign.ocx#version=2,0,0,4" border="0"> </object> </pre> * powercommit <pre> <object id="powercommit" codebase="js/PowerEnter.CAB#version=1,0,0,72" classid="clsid:BEEE2807-1709-4184-A05D-1B2DE01EE4CF" style="width:0px;height:0px" height="0" width="0"> <param name="width" value="0"> <param name="height" value="0"> <param name="frameName" value="mainFrame"> </object> </pre> * powerpassword <pre> <object id="powerpassword" codebase="js/PowerEnter.CAB#version=1,0,0,72" classid="clsid:614E58F9-74D0-4D7B-90E3-64A0F2AA73B4" style="width:186pxpx;height:23pxpx" height="23px" width="186px"> <param name="width" value="186px"> <param name="height" value="23px"> <param name="maxLength" value="20"> <param name="minLength" value="0"> <param name="maskChar" value="*"> <param name="backColor" value="#FFFFFF"> <param name="textColor" value="#000000"> <param name="borderColor" value="#7f9db9"> <param name="accepts" value="*"> <param name="msgBox" value="false"> <param name="fieldName" value="Password"> </object> </pre> == Commit Code == <source lang="javascript"> var blob ="BgIAAACkAABSU0ExAAQAAAEAAQAfFsbhRXwKJMLpsGExRSNaUxLZhaHvMp9ZJEgO2sa30lj6jc2BkNrF/35TKQuLphYVYwDLADdbRj23ChSzVWVmQwAs9CXrqR3tcYavKGsRBEeHEFctULIt6QFn/1Gz6F11k61K8G9yMXy9AGgN+pHum2X3EODpRJBFH9/w1VC+1w=="; function doLogin() { var ran = "<random value>"; if(ran != null && ran !="") { var random = parseFloat(ran)+1; document.form1.ran.value = random; } else { document.form1.ran.value = 0; } var powercommit = document.getElementById("powercommit"); var powerpassword = document.getElementById("powerpassword"); powercommit.reset(); powerpassword.publicKeyBlob(blob); powerpassword.commit("powercommit"); powercommit.submit("form1"); } </source> == Form Params == <source lang="html5"> <form name="form1" action="perlogin1.do" method="post"> <input type="hidden" name="_viewReferer" value="login/login01" /> <input type="hidden" name="_locale" value="zh_CN" /> <input type="hidden" name="version" value="20140529" /> <input type="hidden" name="Password" /> <input type="hidden" name="ran" value="063319703" /> <input type="hidden" name="TransName" value="" /> <input type="hidden" name="Plain" value="" /> <input type="hidden" name="Signature" value="" /> <input type="hidden" name="MerName" value="" /> <input type="hidden" name="TransType" value="" /> <input type="hidden" name="OperationNo" value="" /> <input type="hidden" name="MerDCFlag" value="" /> <input type="hidden" name="checkloginflag" value="" /> <input type="hidden" name="_tokenName" value="1jjihb5u" /> <div class="box"> <!--头部--> <div class=" head"><table cellpadding="0" cellspacing="0" border="0" style="margin:10px 0;"><tr><td align="left" ><img src="images/public/login_2.gif" /></td> </tr> </table> </div> <!--头部结束--> <!--内容--> <div class="content"> <table cellpadding="0" cellspacing="0" border="0"> <tr> <td class="conback" valign="top" > </td> <td class="conback2" valign="top" align="center"> <!--登录区--> <table cellpadding="0" cellspacing="0" border="0" class="login" width="433"> <tr><td valign="top" class="title line01" align="left"><img src="images/public/yhdl.gif" width="120" height="22" /> <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="1" height="1" id="flash" align="middle"> <param name="allowScriptAccess" value="sameDomain"/> <param name="movie" value="/per/bharosa_web/flash/bharosa.swf"/> <param name="quality" value="low"/> <param name="bgcolor" value="#ffffff"/> <param name=FlashVars value="dcUrl=/dc?s=true&"/> <embed src="/per/bharosa_web/flash/bharosa.swf" quality="low" bgcolor="#ffffff" FlashVars="dcUrl=/dc?s=true&" width="1" height="1"name="flash" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash"/> </object> </td></tr> <tr><td height="35" align="center"> </td></tr> <tr><td align="left"> <table cellpadding="0" cellspacing="3" border="0" width="100%"> <tr> <td class="size01 txt02" align="right" width="120">登录名或账号:&nbsp;&nbsp;</td> <td align="left" height="32" width="190"><input name="LoginName" id="skey" value="" class="input_out3" onfocus="this.className='input_on3';this.onmouseout=''" onblur="this.className='input_off3';this.onmouseout=function(){this.className='input_out3'};" type="text" size="16" /></td> <td width="100">&nbsp;</td> </tr> <tr> <td class="size01 txt02" align="right" width="120">登录密码:<img src="images/public/wen.gif" alt="请输入您设置的8~14位网银登录密码"/></td> <td align="left" height="32"> <script type="text/javascript">writePassObject("powerpassword",{"fieldName":"Password","maxLength":"20","minLength":"0","width":"186px","height":"23px","msgBox":"false","maskChar":"*","borderColor":"#7f9db9"});</script> </td> <td align="left"> <a href="####" class="txt_line txt07" onclick="MM_openBrWindow('pwdHelp.do','个人网上银行常见问题解答','width=640,height=420')">密码输入帮助</a> <img id="image1" src="tokenImage.xx?_timesShowToken=2&ran=063319703" style="display:none"/> </td> </tr> <tr><td colspan="3" height="10"></td></tr> <tr><td colspan="3" align="center"> <img src="images/public/denglu_1.gif" onclick="doLogin();" style="cursor: hand"/>&nbsp;&nbsp;&nbsp;&nbsp; </td></tr> </table> </td></tr> <tr><td height="23"></td></tr> <tr><td class="txt08" align="center"><a href="FP320501.do" class="txt07 txt_line">找回登录名</a> | <a href="FP320301.do" class="txt07 txt_line">忘记登录密码</a> | <a href="FP990101.do?ident=gr&idper=ds" class="txt07 txt_line">我要开通网银</a> </td></tr> </table> <!--登录区结束--> </td> </tr> </table> </form> </source> == Sample Form == * username = 11111111 * password = 22222222 <source lang="xml"> <entry method="POST" url="https://www.cebbank.com/per/perlogin1.do"> <timestart>2014-06-19T06:00:43.594Z</timestart> <timeend>2014-06-19T06:00:44.064Z</timeend> <duration>0.470 s</duration> <processname>C:\Program Files\Internet Explorer\iexplore.exe</processname> <result>200 OK</result> <size>0</size> <stage>REQUEST_CLOSE</stage> <mimetype>text/html</mimetype> <redirecturl/> <requestCamefromCache>False</requestCamefromCache> <responseCamefromCache>False</responseCamefromCache> <requestobjectname>/per/perlogin1.do</requestobjectname> <winet_sr_result>True</winet_sr_result> <winet_sr_errormessage/> <bodySize>9333</bodySize> <Web_PageID>0</Web_PageID> <PageTitle/> <Socket_SendSize>0</Socket_SendSize> <Socket_RecvSize>0</Socket_RecvSize> <Starred>False</Starred> <Comment/> <headers> <requestheaders> <header>POST /per/perlogin1.do HTTP/1.1</header> <header>Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, */*</header> <header>Referer: https://www.cebbank.com/per/prePerlogin.do?_locale=zh_CN</header> <header>Accept-Language: en-us</header> <header>User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)</header> <header>Content-Type: application/x-www-form-urlencoded</header> <header>Accept-Encoding: gzip, deflate</header> <header>Host: www.cebbank.com</header> <header>Connection: Keep-Alive</header> <header>Cache-Control: no-cache</header> <header>Cookie: WT_FPC=id=2b3fd12fcdda9131eb91403212946597:lv=1403212951284:ss=1403212946597; cebmemberbranchcode=3550; cebmemberbranchname=%u5317%u4EAC%u5206%u884C; PERJSESSIONID=t6m9Tv0cW5s9jN7JhXFLBhvsbwnG9h4gLn0pyqKgDp97tnNPxdpC!-2124310495; BIGipServerpool_eb_8005=2366482624.17695.0000</header> <header>Content-Length: 388</header> </requestheaders> <responseheaders> <header>HTTP/1.1 200 OK</header> <header>Server: Sun-Java-System-Web-Server/7.0</header> <header>Date: Thu, 19 Jun 2014 10:01:06 GMT</header> <header>Cache-Control: no-cache</header> <header>Date: Thu, 19 Jun 2014 09:59:58 GMT</header> <header>Pragma: No-cache</header> <header>Content-type: text/html; charset=gbk</header> <header>Expires: Thu, 01 Jan 1970 00:00:00 GMT</header> <header>Content-Language: zh-CN</header> <header>X-Powered-By: Servlet/2.5 JSP/2.1</header> <header>Connection: Keep-alive</header> <header>Via: 1.1 AN-0001544151441131</header> <header>Content-Length: 9333</header> </responseheaders> </headers> <content> <contentLength>9333</contentLength> <mimetype>text/html</mimetype> </content> <cookies> <sent> <cookie name=" WT_FPC">id=2b3fd12fcdda9131eb91403212946597:lv=1403212951284:ss=1403212946597</cookie> <cookie name=" cebmemberbranchcode">3550</cookie> <cookie name=" cebmemberbranchname">&#177;&#177;&#190;&#169;&#183;&#214;&#208;&#208;</cookie> <cookie name=" PERJSESSIONID">t6m9Tv0cW5s9jN7JhXFLBhvsbwnG9h4gLn0pyqKgDp97tnNPxdpC!-2124310495</cookie> <cookie name=" BIGipServerpool_eb_8005">2366482624.17695.0000</cookie> </sent> <received/> </cookies> <cache> <BeforeRequest> <UrlInCache>False</UrlInCache> </BeforeRequest> <AfterRequest> <UrlInCache>False</UrlInCache> </AfterRequest> </cache> <QueryString/> <PostData> <mimetype>application/x-www-form-urlencoded</mimetype> <size>388</size> <params> <param name="_viewReferer">login/login01</param> <param name="_locale">zh_CN</param> <param name="version">20140529</param> <param name="Password">XQn0aqYKjJeFutYuXaooFuDF7cAU7jAYd4lpIff/qaZOd1gElxbw/ChRmY1mipjeUlpO0lO8FHO13VaeEyaQf54np25wFo6X2t0LlAKKpruupbDHEWas3pVuajAXsuUqsyqSeDqNlsXpckRWdFBopnzoKuggcgkaMLXsyJtGLU8=</param> <param name="ran">55924190</param> <param name="TransName"/> <param name="Plain"/> <param name="Signature"/> <param name="MerName"/> <param name="TransType"/> <param name="OperationNo"/> <param name="MerDCFlag"/> <param name="checkloginflag"/> <param name="_tokenName">z90qww5h</param> <param name="LoginName">11111111</param> </params> </entry> </source> == API Calls == <pre> CryptImportKey(blob) CryptEncrypt(NULL, 8) -> 128 (128 bytes required) CryptEncrypt(password, 8) -> encrypted pw encrypted pw: 0x03310BD0 D3 5F 47 03 22 A3 0D FA 0C DC 3D BE 06 43 E8 06 ._G.".....=..C.. 0x03310BE0 AF 4D E3 85 80 04 6F 38 46 80 AC F7 E5 79 23 6C .M....o8F....y#l 0x03310BF0 87 E0 D9 81 2B E7 EC 2B AE B7 BB 19 9B A4 13 68 ....+..+.......h 0x03310C00 E9 2B B3 64 80 DE E4 66 66 10 BF D5 56 2A 4E BC .+.d...ff...V*N. 0x03310C10 56 E4 47 66 7E 16 D7 DB 66 B7 05 43 BC AF D6 95 V.Gf~...f..C.... 0x03310C20 AA AD 37 31 0D DE E7 37 7E 71 D2 43 CE 65 1B EB ..71...7~q.C.e.. 0x03310C30 A4 03 03 D7 77 C7 7B A7 41 EA 51 B4 65 70 AD 08 ....w.{.A.Q.ep.. 0x03310C40 63 B3 63 21 84 05 37 F8 6D 2E 74 3C 1A 6A E0 C8 c.c!..7.m.t<.j.. 0x03332BA0 EC 3D A5 ED 3E B1 D7 59 60 9D 36 BA AC CB 22 EA .=..>..Y`.6...". 0x03332BB0 87 15 9A BB 73 D4 39 82 DB 07 3D 66 E7 28 E5 BF ....s.9...=f.(.. 0x03332BC0 6B 2E 0F C9 5E 23 9D 34 DC D2 D7 F3 99 20 A5 1E k...^#.4..... .. 0x03332BD0 56 41 97 F9 38 94 60 A4 7B 36 90 CF 78 99 EA 87 VA..8.`.{6..x... 0x03332BE0 4F 7E 3E 61 68 D8 C4 8E FD ED D3 DF FD 82 38 A1 O~>ah.........8. 0x03332BF0 0B 18 29 14 41 D6 FC C5 3C 3B 6A D1 61 97 17 57 ..).A...<;j.a..W 0x03332C00 E2 D2 F9 0E 11 57 4A AB 16 60 0F 3C 2D 4F DD 07 .....WJ..`.<-O.. 0x03332C10 2B 57 5A 49 3C D2 F4 DF F8 A0 E1 2D 4A DB BF 25 +WZI<......-J..% CryptGenRandom(10) -> random random: 00000000 c8 a4 67 20 dc ef ad ef 6b 79 |..g ....ky| 00000000 d1 f9 3e 73 dc c6 ec f6 47 60 |..>s....G`| CryptCreateHash(MD5) CryptHashData(key1, 21) key1: "csii_powerenter_jason" 0x035092F8 63 73 69 69 5F 70 6F 77 65 72 65 6E 74 65 72 5F csii_powerenter_ 0x03509308 6A 61 73 6F 6E jason CryptDeriveKey(RC4, key1) -> dkey1 CryptEncrypt(dkey1, key2, 16) -> encrypted key2 key2: = base64(random) 0x009AAC78 79 4B 52 6E 49 4E 7A 76 72 65 39 72 65 51 3D 3D yKRnINzvre9reQ== 0x0330FD70 30 66 6B 2B 63 39 7A 47 37 50 5A 48 59 41 3D 3D 0fk+c9zG7PZHYA== encrypted key2: = RC4_encrypt(MD5("csii_powerenter_jason"), base64(random)) 0x009AAC78 D2 5B D6 88 DA F1 04 C6 97 0B 46 48 5F 07 84 D6 .[........FH_... 0x0330FD70 9B 76 EF CD F0 86 04 F7 D2 3E 25 72 63 17 84 D6 .v.......>%rc... CryptHashData(key1, 21) CryptDeriveKey(RC4, key1) -> dkey1 CryptDecrypt(dkey1, sth, 16) -> decrypted sth sth: = encrypted key2 0x03309EC8 EE 42 D4 D1 D5 C5 4D DC 91 3E 4E 70 58 31 84 D6 .B....M..>NpX1.. decrypted sth: = base64(random) = key2 0x03309EC8 45 52 50 37 46 7A 33 6C 74 50 31 4A 62 67 3D 3D ERP7Fz3ltP1Jbg== submit pw: = base64(reverse(encrypted pw)) Jb/bSi3hoPjf9NI8SVpXKwfdTy08D2AWq0pXEQ750uJXF5dh0Wo7PMX81kEUKRgLoTiC/d/T7f2OxNhoYT5+T4fqmXjPkDZ7pGCUOPmXQVYepSCZ89fS3DSdI17JDy5rv+Uo52Y9B9uCOdRzu5oVh+oiy6y6Np1gWdexPu2lPew= 00000000 25 bf db 4a 2d e1 a0 f8 df f4 d2 3c 49 5a 57 2b |%..J-......<IZW+| 00000010 07 dd 4f 2d 3c 0f 60 16 ab 4a 57 11 0e f9 d2 e2 |..O-<.`..JW.....| 00000020 57 17 97 61 d1 6a 3b 3c c5 fc d6 41 14 29 18 0b |W..a.j;<...A.)..| 00000030 a1 38 82 fd df d3 ed fd 8e c4 d8 68 61 3e 7e 4f |.8.........ha>~O| 00000040 87 ea 99 78 cf 90 36 7b a4 60 94 38 f9 97 41 56 |...x..6{.`.8..AV| 00000050 1e a5 20 99 f3 d7 d2 dc 34 9d 23 5e c9 0f 2e 6b |.. .....4.#^...k| 00000060 bf e5 28 e7 66 3d 07 db 82 39 d4 73 bb 9a 15 87 |..(.f=...9.s....| 00000070 ea 22 cb ac ba 36 9d 60 59 d7 b1 3e ed a5 3d ec |."...6.`Y..>..=.| 00000080 ran: 75915681 token: k1ssjcn1 </pre> == Conclusion == submit pw = base64(reverse(encrypted pw)) pw encrypted by the public key in blob through CryptEncrypt() random not used. bd76faa3ea4c9d764ac07f83e5f26797433db07a SQLite Cheatsheet 0 109 376 2014-08-06T18:39:22Z HenryHu 1 以“== types == * text -> str * int -> int * timestamp == where stmt == <pre>where <col1> <op1> <value1> <logic op1> <col2> <op2> <value2> ...</pre> == initialization ...”为内容创建页面 wikitext text/x-wiki == types == * text -> str * int -> int * timestamp == where stmt == <pre>where <col1> <op1> <value1> <logic op1> <col2> <op2> <value2> ...</pre> == initialization == === python / sqlite3 === <pre lang="python"> conn = sqlite3.connect(<db path>, detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES) conn.row_factory = sqlite3.Row </pre> notice: sqlite objects can't be used across different threads == create table == <pre>create table [if not exists] <name> (<col1 name> <col1 type>, <col2 name> <col2 type>, ...)</pre> == drop table == <pre>drop table [if exists] <name></pre> == insert == <pre>insert into <table name> values (?, ?, ...)</pre> == delete == <pre>delete from <table name> where <where stmt></pre> == update == <pre>update <table name> set <col1 name>=?, <col2 name>=?, ...</pre> == query == <pre>select <cols> from <table name> [where <where stmt>] [order by <order col>] [offset <skip count>] [limit <result limit>]</pre> 9c2135f65fce7c7aebc0bdbfe486e11183aaf86e 377 376 2014-08-06T18:40:27Z HenryHu 1 /* update */ wikitext text/x-wiki == types == * text -> str * int -> int * timestamp == where stmt == <pre>where <col1> <op1> <value1> <logic op1> <col2> <op2> <value2> ...</pre> == initialization == === python / sqlite3 === <pre lang="python"> conn = sqlite3.connect(<db path>, detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES) conn.row_factory = sqlite3.Row </pre> notice: sqlite objects can't be used across different threads == create table == <pre>create table [if not exists] <name> (<col1 name> <col1 type>, <col2 name> <col2 type>, ...)</pre> == drop table == <pre>drop table [if exists] <name></pre> == insert == <pre>insert into <table name> values (?, ?, ...)</pre> == delete == <pre>delete from <table name> where <where stmt></pre> == update == <pre>update <table name> set <col1 name>=?, <col2 name>=?, ... where <where stmt></pre> == query == <pre>select <cols> from <table name> [where <where stmt>] [order by <order col>] [offset <skip count>] [limit <result limit>]</pre> 32f7cb5ac39df4fbc1449a5d94919258e17a0181 Reservation 0 91 383 365 2014-08-25T22:57:43Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-08 || 2014-05-17 || Jingyue Wu || Thesis Defend |- || 2014-05-30 || 2014-06-01 || Xu Zhao || Transit to SF |- || 2014-09-05 || 2014-09-07 || Ziling Jiang || visit NY |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng fbd5cc1dc3000b79ec7946552b3c5744eade98a8 384 383 2014-08-25T22:58:53Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-08 || 2014-05-17 || Jingyue Wu || Thesis Defend |- || 2014-05-30 || 2014-06-01 || Xu Zhao || Transit to SF |- || 2014-09-05 || 2014-09-07 || Zilin Jiang || visit NY |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng a5433e39069b5f5c3ec8452cde7b4028df779b20 392 384 2014-09-29T20:15:24Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-08 || 2014-05-17 || Jingyue Wu || Thesis Defend |- || 2014-05-30 || 2014-06-01 || Xu Zhao || Transit to SF |- || 2014-09-05 || 2014-09-07 || Zilin Jiang || visit NY |- || 2014-10-11 || 2014-10-14 || Mina || |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng d5708d8d11635f534f49bfc0efe26fc0630da06d 393 392 2014-09-29T20:20:26Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-08 || 2014-05-17 || Jingyue Wu || Thesis Defend |- || 2014-05-30 || 2014-06-01 || Xu Zhao || Transit to SF |- || 2014-09-05 || 2014-09-07 || Zilin Jiang || visit NY |- || 2014-10-11 || 2014-10-14 || Yu Zhong(Mina) || |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng 9c95a2b0da8ae59b6f747110c64f717c25b6b818 394 393 2014-09-29T20:21:43Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-08 || 2014-05-17 || Jingyue Wu || Thesis Defend |- || 2014-05-30 || 2014-06-01 || Xu Zhao || Transit to SF |- || 2014-09-05 || 2014-09-07 || Zilin Jiang || visit NY |- || 2014-10-11 || 2014-10-13 || Yu Zhong(Mina) || |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng e438310a1aa53ea3699948f5e3170890849215e1 395 394 2014-09-29T20:21:57Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-08 || 2014-05-17 || Jingyue Wu || Thesis Defend |- || 2014-05-30 || 2014-06-01 || Xu Zhao || Transit to SF |- || 2014-09-05 || 2014-09-07 || Zilin Jiang || visit NY |- || 2014-10-11 || 2014-10-14 || Yu Zhong(Mina) || |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng 9c95a2b0da8ae59b6f747110c64f717c25b6b818 396 395 2014-09-29T20:26:18Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-08 || 2014-05-17 || Jingyue Wu || Thesis Defend |- || 2014-05-30 || 2014-06-01 || Xu Zhao || Transit to SF |- || 2014-09-05 || 2014-09-07 || Zilin Jiang || visit NY |- || 2014-10-11 || 2014-10-14 || Yu Zhong(Mina) || Visa |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng 65c23b033626c7bc60ff66912979a5623e1d2b90 397 396 2014-09-29T20:26:50Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-08 || 2014-05-17 || Jingyue Wu || Thesis Defend |- || 2014-09-05 || 2014-09-07 || Zilin Jiang || visit NY |- || 2014-10-11 || 2014-10-14 || Yu Zhong(Mina) || Visa |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng 84e80b7401a117630cbf7bab0ca00e38e5c51366 398 397 2014-09-29T20:28:46Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-08 || 2014-05-17 || Jingyue Wu || Thesis Defend |- || 2014-09-02 || 2014-09-03 || Wenyi Huang || transfer |- || 2014-09-05 || 2014-09-07 || Zilin Jiang || visit NY |- || 2014-10-11 || 2014-10-14 || Yu Zhong(Mina) || Visa |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng b867a55d44d30fc72320a76759b9bb11f0e9216a 400 398 2014-10-10T05:39:21Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-08 || 2014-05-17 || Jingyue Wu || Thesis Defend |- || 2014-09-02 || 2014-09-03 || Wenyi Huang || transfer |- || 2014-09-05 || 2014-09-07 || Zilin Jiang || visit NY |- || 2014-10-11 || 2014-10-14 || Yu Zhong(Mina) || Visa |- || 2014-10-24 || 2014-10-26 || Yun Ling || ? |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng 0152f3d978f2cef431e0a9e3d52691748a812e6c 401 400 2014-10-10T16:34:48Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-08 || 2014-05-17 || Jingyue Wu || Thesis Defend |- || 2014-09-02 || 2014-09-03 || Wenyi Huang || transfer |- || 2014-09-05 || 2014-09-07 || Zilin Jiang || visit NY |- || 2014-10-10 || 2014-10-11 || Xu Zhao || visit |- || 2014-10-11 || 2014-10-14 || Yu Zhong(Mina) || Visa |- || 2014-10-24 || 2014-10-26 || Yun Ling || ? |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng 985f42555f0afc758233cdb66da4c308a24ec654 402 401 2014-10-10T21:01:59Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-08 || 2014-05-17 || Jingyue Wu || Thesis Defend |- || 2014-09-02 || 2014-09-03 || Wenyi Huang || transfer |- || 2014-09-05 || 2014-09-07 || Zilin Jiang || visit NY |- || 2014-10-10 || 2014-10-12 || Xu Zhao || visit |- || 2014-10-10 || 2014-10-11 || Wenyi Huang || visit NY |- || 2014-10-11 || 2014-10-14 || Yu Zhong(Mina) || Visa |- || 2014-10-24 || 2014-10-26 || Yun Ling || ? |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng c40f6640c8de76fd300384ea051f17d92f847d46 403 402 2014-10-12T04:07:29Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-08 || 2014-05-17 || Jingyue Wu || Thesis Defend |- || 2014-09-02 || 2014-09-03 || Wenyi Huang || transfer |- || 2014-09-05 || 2014-09-07 || Zilin Jiang || visit NY |- || 2014-10-09 || 2014-10-12 || Xu Zhao || visit |- || 2014-10-10 || 2014-10-11 || Wenyi Huang || visit NY |- || 2014-10-11 || 2014-10-14 || Yu Zhong(Mina) || Visa |- || 2014-10-24 || 2014-10-26 || Yun Ling || ? |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng 1389bdccbcf92185839147625c12c9213421a61a 407 403 2014-11-24T21:28:47Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-08 || 2014-05-17 || Jingyue Wu || Thesis Defend |- || 2014-09-02 || 2014-09-03 || Wenyi Huang || transfer |- || 2014-09-05 || 2014-09-07 || Zilin Jiang || visit NY |- || 2014-10-09 || 2014-10-12 || Xu Zhao || visit |- || 2014-10-10 || 2014-10-11 || Wenyi Huang || visit NY |- || 2014-10-11 || 2014-10-14 || Yu Zhong(Mina) || Visa |- || 2014-10-24 || 2014-10-26 || Yun Ling || ? |- || 2014-11-25 || 2014-11-30 || Wenyi Huang || visit NY |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng 3c77b5b5bfa9b9502d096ce30950e2eb67eca951 408 407 2014-12-08T20:47:42Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-08 || 2014-05-17 || Jingyue Wu || Thesis Defend |- || 2014-09-02 || 2014-09-03 || Wenyi Huang || transfer |- || 2014-09-05 || 2014-09-07 || Zilin Jiang || visit NY |- || 2014-10-09 || 2014-10-12 || Xu Zhao || visit |- || 2014-10-10 || 2014-10-11 || Wenyi Huang || visit NY |- || 2014-10-11 || 2014-10-14 || Yu Zhong(Mina) || Visa |- || 2014-10-24 || 2014-10-26 || Yun Ling || ? |- || 2014-11-25 || 2014-11-30 || Wenyi Huang || visit NY |- || 2014-12-22 || 2014-12-30 || Ruizhang Jin || Christmas |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng 27760ccb3757aab5137c1b977e7010bd1937fc2f 409 408 2014-12-09T00:04:02Z HenryHu 1 /* Room Reservation */ wikitext text/x-wiki Reservation status of my home == Room Reservation == {| class="wikitable" ! Start date !! End date || Who || For |- || 2012-08-16 || 2012-08-18 || Xuetian Weng || Before he finds his home... |- || 2012-08-25 || 2012-08-26 || Yilei Yang || Before he finds home... |- || 2012-08-26 || None || Yue Liu || Before he finds home... |- || 2012-08-30 || 2012-08-31 || Xin Zhou || Interview |- || 2012-08-30 || 2012-09-02 || Xin He || Stay for a while before he goes back school |- || 2012-11-20 || 2012-11-22 || Xin He || Stay for several days |- || 2012-11-22 || 2012-11-24 || Dong Zhou || Stay for several days |- || 2012-12-16 || 2012-12-18 || Dong Zhou || Stay before boarding the plane |- || 2012-12-18 || 2012-12-20 || Xin He || Stay before boarding the plane |- || 2012-12-27 || 2012-12-29 || Yucheng Zhang || Tour |- || 2012-12-31 || 2013-01-02 || Tianfan Xue || ? |- || 2013-12-22 || 2013-12-27 || Wenyi Huang || Stay for the Christmas |- || 2014-02-01 || ? || Anqi Cui || ? |- || 2014-05-08 || 2014-05-17 || Jingyue Wu || Thesis Defend |- || 2014-09-02 || 2014-09-03 || Wenyi Huang || transfer |- || 2014-09-05 || 2014-09-07 || Zilin Jiang || visit NY |- || 2014-10-09 || 2014-10-12 || Xu Zhao || visit |- || 2014-10-10 || 2014-10-11 || Wenyi Huang || visit NY |- || 2014-10-11 || 2014-10-14 || Yu Zhong(Mina) || Visa |- || 2014-10-24 || 2014-10-26 || Yun Ling || ? |- || 2014-11-25 || 2014-11-30 || Wenyi Huang || visit NY |- || 2014-12-13 || ? || Ruizhang Jin || Christmas |} == History == * Wenyi Huang * Xin He * Huayang Guo * Haichen Shen & his friend * Xuetian Weng babc5f8ecd9111c3746dd519b2d948f67f424b1f Xprop 0 110 385 2014-09-02T03:56:14Z HenryHu 1 以“xprop不止可以读取窗口属性,还能改哦! == 方法 == <pre>xprop -set <prop name> <prop value></pre> 当然,多数prop需要先指定format。 <pre>...”为内容创建页面 wikitext text/x-wiki xprop不止可以读取窗口属性,还能改哦! == 方法 == <pre>xprop -set <prop name> <prop value></pre> 当然,多数prop需要先指定format。 <pre>-format <prop name> <format></pre> 其中format以0/8/16/32开头,后面跟一些类型描述。具体参见manpage。比如a表示atom,s表示字符串,u表示utf-8字符串…… == 样例 == === 修改STATE === xprop -id <window id> -format _NET_WM_STATE 32a -set _NET_WM_STATE <value> 可用value: * _NET_WM_STATE_SKIP_TASKBAR 不出现在任务栏 == 配合xdotool == xdotool有个search功能挺好用。他本来也能set_window只是比较弱。 <pre>xdotool search [--name <name>] [--class <class>] [--classname <classname>]</pre> 先xdotool找再xprop改: <pre>xdotool search [args] | xargs -I %i xprop -id %i [cmd]</pre> e9685a173d3fb3c89dd8692441da8d388146f91f 386 385 2014-09-02T03:58:41Z HenryHu 1 /* 配合xdotool */ wikitext text/x-wiki xprop不止可以读取窗口属性,还能改哦! == 方法 == <pre>xprop -set <prop name> <prop value></pre> 当然,多数prop需要先指定format。 <pre>-format <prop name> <format></pre> 其中format以0/8/16/32开头,后面跟一些类型描述。具体参见manpage。比如a表示atom,s表示字符串,u表示utf-8字符串…… == 样例 == === 修改STATE === xprop -id <window id> -format _NET_WM_STATE 32a -set _NET_WM_STATE <value> 可用value: * _NET_WM_STATE_SKIP_TASKBAR 不出现在任务栏 == 配合xdotool == xdotool有个search功能挺好用。他本来也能set_window只是比较弱。 <pre>xdotool search [--name <name>] [--class <class>] [--classname <classname>]</pre> 先xdotool找再xprop改: <pre>xdotool search [args] | xargs -I %i xprop -id %i [cmd]</pre> == 综合 == === 某些弱智wine窗口不出现在任务栏 === Wine程序的class是Wine,classname貌似是执行文件名。 <pre>xdotool search --class Wine | xargs -I %i xprop -id %i -format _NET_WM_STATE 32a -set _NET_WM_STATE _NET_WM_STATE_NONE</pre> 当然这个_NET_WM_STATE_NONE是我瞎掰的…… 8825385240d8361654b834900c4d22511989acce 387 386 2014-09-02T04:04:50Z HenryHu 1 /* 配合xdotool */ wikitext text/x-wiki xprop不止可以读取窗口属性,还能改哦! == 方法 == <pre>xprop -set <prop name> <prop value></pre> 当然,多数prop需要先指定format。 <pre>-format <prop name> <format></pre> 其中format以0/8/16/32开头,后面跟一些类型描述。具体参见manpage。比如a表示atom,s表示字符串,u表示utf-8字符串…… == 样例 == === 修改STATE === xprop -id <window id> -format _NET_WM_STATE 32a -set _NET_WM_STATE <value> 可用value: * _NET_WM_STATE_SKIP_TASKBAR 不出现在任务栏 == 配合xdotool == xdotool有个search功能挺好用。他本来也能set_window只是比较弱。 <pre>xdotool search [--name <name>] [--class <class>] [--classname <classname>]</pre> xdotool还有个selectwindow的功能,可以指哪儿打哪儿: <pre>xdotool selectwindow</pre> 先xdotool找再xprop改: <pre>xdotool search [args] | xargs -I %i xprop -id %i [cmd]</pre> == 综合 == === 某些弱智wine窗口不出现在任务栏 === Wine程序的class是Wine,classname貌似是执行文件名。 <pre>xdotool search --class Wine | xargs -I %i xprop -id %i -format _NET_WM_STATE 32a -set _NET_WM_STATE _NET_WM_STATE_NONE</pre> 当然这个_NET_WM_STATE_NONE是我瞎掰的…… d79fde6b185d7ca230ccf69eadf699b6b017da1d Futex 0 111 388 2014-09-05T02:56:59Z HenryHu 1 以“futex: 比较快的大部分时间都只需要user space操作的mutex source: [http://locklessinc.com/articles/futex_cheat_sheet/ Futex Cheat Sheet] [http://lwn...”为内容创建页面 wikitext text/x-wiki futex: 比较快的大部分时间都只需要user space操作的mutex source: [http://locklessinc.com/articles/futex_cheat_sheet/ Futex Cheat Sheet] [http://lwn.net/Articles/360699/ A futex overview] [https://www.kernel.org/doc/Documentation/pi-futex.txt Lightweight PI-futexes] [https://www.kernel.org/doc/Documentation/rt-mutex.txt RT-mutex subsystem with PI support] == 目的 == 在没有竞争的情况下,futex不需要调用system call。每个用户线程执行一个atomic operation,没有竞争的情况下根据返回值就可以直接成功,unlock的时候也差不多。 在有竞争的情况下,后到的线程在atomic op之后会发现mutex已经被人用了,于是调用FUTEX_WAIT来等。 有竞争时,unlock的atomic op会让解锁线程发现有其他人在等,于是就会调用FUTEX_WAKE来唤醒其他人。 == API == linux有个很毛的复用了的api,叫做futex。基本形式是 <pre>futex(op, arg1, arg2, ...)</pre> 其中第一个参数决定了进行哪种futex操作,同时决定了后面的参数里面有几个有用以及分别是什么意思…… == PI:问题和解决 == 关于mutex,有一个优先级反转问题。 说有三个线程优先级是high, med和low。high和low共享一个mutex。假如某天low抓到了mutex,之后high也去抓这个mutex,那high就会开始等。如果这个时候med把low给抢了,那low就会不知道被抢多久。因为high也在等那个mutex,high也会不知道被卡多久。 在这个情况下,明明优先级比high低,但是med却导致high没法继续跑。这就是优先级反转问题。 为了解决这个问题,一个办法是暂时提高low的优先级。因为high也在等,所以暂时把low提到和high一样高。这样它就不会被med抢,从而也就不会卡high了。 futex有一堆操作都是为了解决这个问题,这些操作都以_PI结尾。PI说的是priority inherit,让low的thread能够继承high thread的priority。 == private优化 == 说futex设计的时候是可以多进程公用的。只要你们搞个shared mem,然后把同一个地方传给那些futex操作,那你们就可以共享mutex,在多个进程之间。 但是对于那些单进程的mutex,这样降低了效率。kernel需要先查一遍才知道这个地址对应的物理地址,然后才能拿来作为索引。但其实单进程里面只要直接拿虚拟地址搞就可以了。 所以好多操作还有个private版本,告诉kernel你不用翻译地址了。这些操作基本上就是在老操作上or一个FUTEX_PRIVATE_FLAG,当然也有定义好的_PRIVATE的常数,可以直接用。 == BITSET == FUTEX_WAKE和FUTEX_WAIT有个带BITSET的版本,多一个mask参数。说WAKE的时候,只有这个mask和WAIT时候的mask有相交的才起作用。 实际上相当于多个wait queue可以共享一个地址。但是说后来发现这样实现没效率,所以glibc现在只用mask全满的情况,也就是相当于和老的一样。 那为啥不用老的呢?因为BITSET版本还有个不同:他的timeout是绝对时间,而老版本是相对时间,但是pthread标准要求绝对时间…… == 操作 == === 基本操作 === ==== FUTEX_WAIT ==== FUTEX_WAIT提供一个地址和一个值。进syscall之后,首先观察那个地址是不是那个值,如果不是直接返回。否则开始等。 ==== FUTEX_WAKE ==== FUTEX_WAKE提供一个地址和一个数量,唤醒等在这个地址的指定数量的thread。 ==== FUTEX_REQUEUE ==== FUTEX_REQUEUE提供两个地址,以及两个数量。唤醒若干等在第一个地址的线程,同时把另外一些扔到等待第二个地址的队列中去。 这个用在conditional variable上。试想一个cond broadcast唤醒了所有人,这帮人接下来一起去抢控制cond var那个mutex。这很没有效率,所以不如直接唤醒一个,把剩下的扔到等那个mutex的队列里去。所以其实也是个效率优化。 ==== FUTEX_CMP_REQUEUE ==== 比起FUTEX_REQUEUE,这货多一个参数。如果给定的第一个地址里面的内容和这个参数不同,返回EAGAIN。 说glibc里面的cond var实现很复杂,还和另一个mutex有关系,所以要搞这个…… === PI操作 === ==== FUTEX_LOCK_PI ==== 如果你锁一个PI mutex的时候发现被人占了,那就调用这个syscall。系统会帮你搞定提高别人优先级的事情。 ==== FUTEX_UNLOCK_PI ==== 如果你解锁一个PI mutex的时候发现有人等,那就调用这个。系统会帮你降低优先级的。 === BITSET === ==== FUTEX_WAIT_BITSET ==== 比FUTEX_WAIT多一个bitmap。对应的WAKE_BITSET里的bitmap如果和这个有相交的那就WAKE,否则忽略。 ==== FUTEX_WAKE_BITSET ==== 比FUTEX_WAKE多一个bitmap。只wake那些WAIT_BITSET的bitmap里和这个bitmap有相交的线程。 === 过时的操作 === ==== FUTEX_FD ==== 说有race condition来着。 ==== FUTEX_WAKE_OP ==== 说更新存在给定地址里的内容,然后判断一下,成功了再唤醒来着…… 8fd3b9f8ed505aaa2dff9ab09c40a0c60758e96b Library version numbers 0 112 389 2014-09-08T18:44:27Z HenryHu 1 以“source: http://openbooks.sourceforge.net/books/wga/dealing-with-libraries.html 你看,其实库的版本号当初是有含义的。 一般我们看见库版本号...”为内容创建页面 wikitext text/x-wiki source: http://openbooks.sourceforge.net/books/wga/dealing-with-libraries.html 你看,其实库的版本号当初是有含义的。 一般我们看见库版本号有a:b:c,正规含义是Current:Revision:Age。 Current在每次公开接口变化的时候都要变,不管是否向后兼容。 Revision在不变公开接口只是内部代码变化的时候变。变公开接口的时候应该归零。 Age表示向后兼容多少版本(不包括自己)。说如果Current是6但是你兼容4和5那Age就是2。 其实Age定义挺反人类的,定义成Current-Age多好…… 2e798292a9622dad0568cb95bb52a64ca3480c48 Ioctl 0 113 390 2014-09-12T04:50:50Z HenryHu 1 以“== Linux == === fields === IOC_NRBITS 8 IOC_TYPEBITS 8 IOC_SIZEBITS 14 IOC_DIRBITS 2 IOC_NRSHIFT 0 IOC_TYPESHIFT IOC_NRSHIFT+IOC_NRBITS = 8 IOC_SIZESHIFT IOC_TYPESH...”为内容创建页面 wikitext text/x-wiki == Linux == === fields === IOC_NRBITS 8 IOC_TYPEBITS 8 IOC_SIZEBITS 14 IOC_DIRBITS 2 IOC_NRSHIFT 0 IOC_TYPESHIFT IOC_NRSHIFT+IOC_NRBITS = 8 IOC_SIZESHIFT IOC_TYPESHIFT + IOC_TYPESIZE = 16 IOC_DIRSHIFT IOC_SIZESHIFT + IOC_SIZEBITS = 30 DIR (2) | SIZE(14) | TYPE(8) | NR(8) IOC(dir, type, nr, size) dir << dirshift | type << typeshift | nr << nrshift | size << sizeshift === direction === IOC_NONE 0 IOC_WRITE 1 IOC_READ 2 === example === 0x8b01 type=8b(wireless) nr=01 427990fb0d5f1a10a0c26f26afd8bf8eb31aedd0 Scancode mapping 0 114 391 2014-09-14T02:42:51Z HenryHu 1 以“Mapping from scancode to keycode == FreeBSD == * 0x54 -> 92 <SYRQ> * 0x55, 56, 57, 58, 59 -> 93, 94, 95, 96 <I15D, LSGT, F11, F12> * 0x59 -> 157 <K59> * 0x5a -> 17...”为内容创建页面 wikitext text/x-wiki Mapping from scancode to keycode == FreeBSD == * 0x54 -> 92 <SYRQ> * 0x55, 56, 57, 58, 59 -> 93, 94, 95, 96 <I15D, LSGT, F11, F12> * 0x59 -> 157 <K59> * 0x5a -> 170 <K5A> * 0x5b, 5c, 5d, 5e -> 181, 126, 182, 183 <K5B, KPEQ/K5C, K5D, K5E> * 0x5f -> 184 <K5F> * 0x60 -> 113? * 0x61 -> 148 <I14> * 0x62 -> 189 <K62> * 0x63 -> 190 <K63> * 0x64 ... 0x6e (11) -> 191, 192, 193, 198, 199, 200, 201, 203, 204, 205, 206 <K64 .. K6E> * 0x6f -> 207 <K6F> * 0x70 -> 208 <K70> * 0x71 -> 209 <K71> * 0x72 -> 210 <K72> * 0x73 -> 211 <K73> * 0x74 -> 219 <K74> * 0x75 -> 220 <K75> * 0x76 -> 221 <K76> * 0x77, 78, 79 -> 127, 128, 129 <SUPR, HYPR, XFER> * 0x7a -> 130 <I02> * 0x7b -> 131 <NFER> * 0x7c -> 132 <I04> * 0x7d, 7e, 7f -> 133, 134, 135 <AE13/I05, I06, I07> b3209c0269d5a72381c97d67c1f56acd8d1b666f Bug 0 115 399 2014-10-01T00:39:09Z HenryHu 1 以“* Find a bug / Get report of a bug ** KLEE: crash bugs ** STACK: undefined behavior * Reproduce the bug ** DMT ** Record-replay ** stress test * Diagnose the bug ** ...”为内容创建页面 wikitext text/x-wiki * Find a bug / Get report of a bug ** KLEE: crash bugs ** STACK: undefined behavior * Reproduce the bug ** DMT ** Record-replay ** stress test * Diagnose the bug ** printf ** DTrace * Fix the bug ** AFIX/CFIX/OFIX * Create regression test for the bug * Find other bugs with the same pattern 48ba41e7a361545c0742b7b913384e3ddbcc699b Mono 0 116 404 2014-10-21T22:03:40Z HenryHu 1 以“== 编译一个static native executable == <pre> mkbundle --static --deps -o xxx xxx.exe yyy.dll </pre> 其中: * --static: 包含libmono。否则产生的可执...”为内容创建页面 wikitext text/x-wiki == 编译一个static native executable == <pre> mkbundle --static --deps -o xxx xxx.exe yyy.dll </pre> 其中: * --static: 包含libmono。否则产生的可执行程序依赖libmono * --deps: 把依赖的dll也一起打包进去 另外还有mkbundle2,会用.Net 2.0 profile(啥……)。 ed26f73f574a97b3fda67163dfeee97bc6b699ac VirtualBox 0 117 405 2014-11-22T18:44:23Z HenryHu 1 以“== 切换WinXP为多核 == 如果开了多核之后,WinXP还是只有单核: 搜索下载HALu.zip,运行后替换成ACPI Multiprocessor PC即可。”为内容创建页面 wikitext text/x-wiki == 切换WinXP为多核 == 如果开了多核之后,WinXP还是只有单核: 搜索下载HALu.zip,运行后替换成ACPI Multiprocessor PC即可。 48c5f5cc2bcad51527acbc101e8e845124e519dc Grub4dos 0 118 406 2014-11-24T04:34:24Z HenryHu 1 以“关于神器grub4dos的使用方法。 == 安装 == 首先,用启动盘启动到dos里。 然后,bootlace.com 0xyy 其中,yy指定了目标盘。根据是BIO...”为内容创建页面 wikitext text/x-wiki 关于神器grub4dos的使用方法。 == 安装 == 首先,用启动盘启动到dos里。 然后,bootlace.com 0xyy 其中,yy指定了目标盘。根据是BIOS硬盘号,第一块是80,第二块是81…… 如果不确定,可以从启动盘跑个grub,然后ls看一下。顺序和bios是一样的。 这个会把grub4dos的MBR部分装进去。 其次,把grldr拷到某个分区的根目录下面。 NTFS/FAT都行,不是第一个分区也可以。当然,越靠前那么grub找到得越快。 最后写个menu.lst,就完工了。menu.lst也可以放到根目录。 == 光盘启动 == 多数光盘其实都跑不起来。 * 首先 map --mem /xxx.iso (hd32) * 其次 map --hook * 再次 chainloader (hd32) * 最后 boot 因为本质上是替换了某个中断调用,那些光盘里的系统加载了驱动之后,就会发现光盘不见了,然后就挂了…… --mem不一定需要,如果加了那会把光盘内容先读到内存里,很慢…… ecd6c5495d63589e768dd4b2a2661a70c0d0451a Iced tea 0 119 410 2014-12-13T20:28:26Z HenryHu 1 以“== 排序分先后 == Brisk ICED TEA LEMON falvour Turkey Hill Arizona Tea”为内容创建页面 wikitext text/x-wiki == 排序分先后 == Brisk ICED TEA LEMON falvour Turkey Hill Arizona Tea ffe4436d67f963354bb6400d2f816354bbedd128 Hints 0 120 411 2014-12-20T02:14:44Z HenryHu 1 以“* Undefined symbol "PL_thr_key" referenced from COPY relocation in /usr/local/bin/vim 重装perl,打开threads支持”为内容创建页面 wikitext text/x-wiki * Undefined symbol "PL_thr_key" referenced from COPY relocation in /usr/local/bin/vim 重装perl,打开threads支持 1985dff4906c9b5802d0bd19ee9a7b31ec3e4f8e Bilibili 0 121 412 2014-12-20T05:09:27Z HenryHu 1 以“== 关于卡 == B站搞了个测试功能,于是可以观察各个源的情况。 === 获得视频地址 === 首先找interface.bilibili.com问视频在哪。目...”为内容创建页面 wikitext text/x-wiki == 关于卡 == B站搞了个测试功能,于是可以观察各个源的情况。 === 获得视频地址 === 首先找interface.bilibili.com问视频在哪。目前这个请求是不加密的,有篡改的希望。或者干脆把interface.bilibili.com解析到本地,然后过滤http流量。 随后地址里的域名会被解析。这个过程是可控的。 === 新浪 === 新浪主要有俩域名: * v.iask.com 应该是主站吧 ** 202.108.37.55 北京 联通 ** 60.28.164.251 天津 联通 * edge.v.iask.com.lxdns.com 某CDN的节点,正规名为www.ipswitch.glb0.lxdns.com ** 121.14.35.240 广州 电信 ** 115.231.132.57 杭州 电信 ** 70.39.191.158 LA 首先是给个域名,然后从域名解析出IP。 对前一个域名,北京节点的网速比天津好多了;对后一个域名,当然是LA好。 通过在DNS上固定解析,可以绑定域名和IP。<已实行> 要固定返回的域名…… 可能要改写HTTP请求结果了。 === 乐视 === * g3.letv.cn ** 115.182.51.175 北京 (巨快) ** 117.121.54.219 北京 电信 === B站 === * cc.acgvideo.com 正规名 cc00009.f.cncssr.chinacache.net ** 123.235.32.130 ** 36.250.90.194 福建省 联通 very slow <50kB/s lag >1000ms ** 182.118.9.130 河南省 联通 ok ** 221.194.130.206 河北省 联通 slow <100kB/s smooth ** 119.6.246.137 四川省 联通 very slow <50kB/s lag >1000ms ** 210.76.57.147 黑龙江 联通 very slow <50kB/s lag >1000ms ** 112.84.133.214 varies/ok === 优酷 === * k.youku.com ** 119.167.145.95 fast 200~2200kB/s ok 800~1100ms ** 还有很多119.167.145.* 都差不多 ec9ff68e8413d9839f59beb69740db5ea77a93be 413 412 2014-12-20T05:16:38Z HenryHu 1 /* 优酷 */ wikitext text/x-wiki == 关于卡 == B站搞了个测试功能,于是可以观察各个源的情况。 === 获得视频地址 === 首先找interface.bilibili.com问视频在哪。目前这个请求是不加密的,有篡改的希望。或者干脆把interface.bilibili.com解析到本地,然后过滤http流量。 随后地址里的域名会被解析。这个过程是可控的。 === 新浪 === 新浪主要有俩域名: * v.iask.com 应该是主站吧 ** 202.108.37.55 北京 联通 ** 60.28.164.251 天津 联通 * edge.v.iask.com.lxdns.com 某CDN的节点,正规名为www.ipswitch.glb0.lxdns.com ** 121.14.35.240 广州 电信 ** 115.231.132.57 杭州 电信 ** 70.39.191.158 LA 首先是给个域名,然后从域名解析出IP。 对前一个域名,北京节点的网速比天津好多了;对后一个域名,当然是LA好。 通过在DNS上固定解析,可以绑定域名和IP。<已实行> 要固定返回的域名…… 可能要改写HTTP请求结果了。 === 乐视 === * g3.letv.cn ** 115.182.51.175 北京 (巨快) ** 117.121.54.219 北京 电信 === B站 === * cc.acgvideo.com 正规名 cc00009.f.cncssr.chinacache.net ** 123.235.32.130 ** 36.250.90.194 福建省 联通 very slow <50kB/s lag >1000ms ** 182.118.9.130 河南省 联通 ok ** 221.194.130.206 河北省 联通 slow <100kB/s smooth ** 119.6.246.137 四川省 联通 very slow <50kB/s lag >1000ms ** 210.76.57.147 黑龙江 联通 very slow <50kB/s lag >1000ms ** 112.84.133.214 varies/ok === 优酷 === * k.youku.com ** 119.167.145.95 fast 200~2200kB/s ok 800~1100ms ** 还有很多119.167.145.* 都差不多 === PPTV === 反正看不了 e6d8550386061092e4f33f4533d0d7d9d9c76d8b 414 413 2014-12-20T05:16:49Z HenryHu 1 /* 乐视 */ wikitext text/x-wiki == 关于卡 == B站搞了个测试功能,于是可以观察各个源的情况。 === 获得视频地址 === 首先找interface.bilibili.com问视频在哪。目前这个请求是不加密的,有篡改的希望。或者干脆把interface.bilibili.com解析到本地,然后过滤http流量。 随后地址里的域名会被解析。这个过程是可控的。 === 新浪 === 新浪主要有俩域名: * v.iask.com 应该是主站吧 ** 202.108.37.55 北京 联通 ** 60.28.164.251 天津 联通 * edge.v.iask.com.lxdns.com 某CDN的节点,正规名为www.ipswitch.glb0.lxdns.com ** 121.14.35.240 广州 电信 ** 115.231.132.57 杭州 电信 ** 70.39.191.158 LA 首先是给个域名,然后从域名解析出IP。 对前一个域名,北京节点的网速比天津好多了;对后一个域名,当然是LA好。 通过在DNS上固定解析,可以绑定域名和IP。<已实行> 要固定返回的域名…… 可能要改写HTTP请求结果了。 === 乐视 === * g3.letv.cn ** 115.182.51.175 北京 (巨快) ** 117.121.54.219 北京 电信 其实看不了,只有广告 === B站 === * cc.acgvideo.com 正规名 cc00009.f.cncssr.chinacache.net ** 123.235.32.130 ** 36.250.90.194 福建省 联通 very slow <50kB/s lag >1000ms ** 182.118.9.130 河南省 联通 ok ** 221.194.130.206 河北省 联通 slow <100kB/s smooth ** 119.6.246.137 四川省 联通 very slow <50kB/s lag >1000ms ** 210.76.57.147 黑龙江 联通 very slow <50kB/s lag >1000ms ** 112.84.133.214 varies/ok === 优酷 === * k.youku.com ** 119.167.145.95 fast 200~2200kB/s ok 800~1100ms ** 还有很多119.167.145.* 都差不多 === PPTV === 反正看不了 c269a57acc997fe20473cb4d233b87adcabecba2 415 414 2014-12-20T05:17:00Z HenryHu 1 /* 乐视 */ wikitext text/x-wiki == 关于卡 == B站搞了个测试功能,于是可以观察各个源的情况。 === 获得视频地址 === 首先找interface.bilibili.com问视频在哪。目前这个请求是不加密的,有篡改的希望。或者干脆把interface.bilibili.com解析到本地,然后过滤http流量。 随后地址里的域名会被解析。这个过程是可控的。 === 新浪 === 新浪主要有俩域名: * v.iask.com 应该是主站吧 ** 202.108.37.55 北京 联通 ** 60.28.164.251 天津 联通 * edge.v.iask.com.lxdns.com 某CDN的节点,正规名为www.ipswitch.glb0.lxdns.com ** 121.14.35.240 广州 电信 ** 115.231.132.57 杭州 电信 ** 70.39.191.158 LA 首先是给个域名,然后从域名解析出IP。 对前一个域名,北京节点的网速比天津好多了;对后一个域名,当然是LA好。 通过在DNS上固定解析,可以绑定域名和IP。<已实行> 要固定返回的域名…… 可能要改写HTTP请求结果了。 === 乐视 === * g3.letv.cn ** 115.182.51.175 北京 (巨快) ** 117.121.54.219 北京 电信 有的其实看不了,只有广告 === B站 === * cc.acgvideo.com 正规名 cc00009.f.cncssr.chinacache.net ** 123.235.32.130 ** 36.250.90.194 福建省 联通 very slow <50kB/s lag >1000ms ** 182.118.9.130 河南省 联通 ok ** 221.194.130.206 河北省 联通 slow <100kB/s smooth ** 119.6.246.137 四川省 联通 very slow <50kB/s lag >1000ms ** 210.76.57.147 黑龙江 联通 very slow <50kB/s lag >1000ms ** 112.84.133.214 varies/ok === 优酷 === * k.youku.com ** 119.167.145.95 fast 200~2200kB/s ok 800~1100ms ** 还有很多119.167.145.* 都差不多 === PPTV === 反正看不了 3445620f30d29aac0a91ed313dadcf465d37125a Bilibili 0 121 416 415 2014-12-20T05:20:12Z HenryHu 1 /* B站 */ wikitext text/x-wiki == 关于卡 == B站搞了个测试功能,于是可以观察各个源的情况。 === 获得视频地址 === 首先找interface.bilibili.com问视频在哪。目前这个请求是不加密的,有篡改的希望。或者干脆把interface.bilibili.com解析到本地,然后过滤http流量。 随后地址里的域名会被解析。这个过程是可控的。 === 新浪 === 新浪主要有俩域名: * v.iask.com 应该是主站吧 ** 202.108.37.55 北京 联通 ** 60.28.164.251 天津 联通 * edge.v.iask.com.lxdns.com 某CDN的节点,正规名为www.ipswitch.glb0.lxdns.com ** 121.14.35.240 广州 电信 ** 115.231.132.57 杭州 电信 ** 70.39.191.158 LA 首先是给个域名,然后从域名解析出IP。 对前一个域名,北京节点的网速比天津好多了;对后一个域名,当然是LA好。 通过在DNS上固定解析,可以绑定域名和IP。<已实行> 要固定返回的域名…… 可能要改写HTTP请求结果了。 === 乐视 === * g3.letv.cn ** 115.182.51.175 北京 (巨快) ** 117.121.54.219 北京 电信 有的其实看不了,只有广告 === B站 === * us-chicago.acgvideo.com ** 67.159.54.58 Chicago slow <100kB/s varies 700~5000ms * cc.acgvideo.com 正规名 cc00009.f.cncssr.chinacache.net ** 123.235.32.130 ** 36.250.90.194 福建省 联通 very slow <50kB/s lag >1000ms ** 182.118.9.130 河南省 联通 varies 30~300kB/s ** 221.194.130.206 河北省 联通 slow <100kB/s smooth ** 119.6.246.137 四川省 联通 very slow <50kB/s lag >1000ms ** 210.76.57.147 黑龙江 联通 very slow <50kB/s lag >1000ms ** 112.84.133.214 varies/ok === 优酷 === * k.youku.com ** 119.167.145.95 fast 200~2200kB/s ok 800~1100ms ** 还有很多119.167.145.* 都差不多 === PPTV === 反正看不了 3dd699341c848d679c47376f24a1321868ee4394 417 416 2014-12-21T19:40:11Z HenryHu 1 /* 优酷 */ wikitext text/x-wiki == 关于卡 == B站搞了个测试功能,于是可以观察各个源的情况。 === 获得视频地址 === 首先找interface.bilibili.com问视频在哪。目前这个请求是不加密的,有篡改的希望。或者干脆把interface.bilibili.com解析到本地,然后过滤http流量。 随后地址里的域名会被解析。这个过程是可控的。 === 新浪 === 新浪主要有俩域名: * v.iask.com 应该是主站吧 ** 202.108.37.55 北京 联通 ** 60.28.164.251 天津 联通 * edge.v.iask.com.lxdns.com 某CDN的节点,正规名为www.ipswitch.glb0.lxdns.com ** 121.14.35.240 广州 电信 ** 115.231.132.57 杭州 电信 ** 70.39.191.158 LA 首先是给个域名,然后从域名解析出IP。 对前一个域名,北京节点的网速比天津好多了;对后一个域名,当然是LA好。 通过在DNS上固定解析,可以绑定域名和IP。<已实行> 要固定返回的域名…… 可能要改写HTTP请求结果了。 === 乐视 === * g3.letv.cn ** 115.182.51.175 北京 (巨快) ** 117.121.54.219 北京 电信 有的其实看不了,只有广告 === B站 === * us-chicago.acgvideo.com ** 67.159.54.58 Chicago slow <100kB/s varies 700~5000ms * cc.acgvideo.com 正规名 cc00009.f.cncssr.chinacache.net ** 123.235.32.130 ** 36.250.90.194 福建省 联通 very slow <50kB/s lag >1000ms ** 182.118.9.130 河南省 联通 varies 30~300kB/s ** 221.194.130.206 河北省 联通 slow <100kB/s smooth ** 119.6.246.137 四川省 联通 very slow <50kB/s lag >1000ms ** 210.76.57.147 黑龙江 联通 very slow <50kB/s lag >1000ms ** 112.84.133.214 varies/ok === 优酷 === * k.youku.com ** 119.167.145.95 fast 200~2200kB/s ok 800~1100ms ** 还有很多119.167.145.* 都差不多 ** 113.103.44.51 fast ok === PPTV === 反正看不了 684b43fb4c666c49f434bcbe971c8be791a2ca58 418 417 2014-12-21T21:06:04Z HenryHu 1 /* B站 */ wikitext text/x-wiki == 关于卡 == B站搞了个测试功能,于是可以观察各个源的情况。 === 获得视频地址 === 首先找interface.bilibili.com问视频在哪。目前这个请求是不加密的,有篡改的希望。或者干脆把interface.bilibili.com解析到本地,然后过滤http流量。 随后地址里的域名会被解析。这个过程是可控的。 === 新浪 === 新浪主要有俩域名: * v.iask.com 应该是主站吧 ** 202.108.37.55 北京 联通 ** 60.28.164.251 天津 联通 * edge.v.iask.com.lxdns.com 某CDN的节点,正规名为www.ipswitch.glb0.lxdns.com ** 121.14.35.240 广州 电信 ** 115.231.132.57 杭州 电信 ** 70.39.191.158 LA 首先是给个域名,然后从域名解析出IP。 对前一个域名,北京节点的网速比天津好多了;对后一个域名,当然是LA好。 通过在DNS上固定解析,可以绑定域名和IP。<已实行> 要固定返回的域名…… 可能要改写HTTP请求结果了。 === 乐视 === * g3.letv.cn ** 115.182.51.175 北京 (巨快) ** 117.121.54.219 北京 电信 有的其实看不了,只有广告 === B站 === * us-chicago.acgvideo.com ** 67.159.54.58 Chicago slow <100kB/s varies 700~5000ms * cc.acgvideo.com 正规名 cc00009.f.cncssr.chinacache.net ** 123.235.32.130 ** 36.250.90.194 福建省 联通 very slow <50kB/s lag >1000ms ** 182.118.9.130 河南省 联通 varies 30~300kB/s ** 221.194.130.206 河北省 联通 slow <100kB/s smooth ** 119.6.246.137 四川省 联通 very slow <50kB/s lag >1000ms ** 210.76.57.147 黑龙江 联通 very slow <50kB/s lag >1000ms ** 112.84.133.214 varies/ok 前一个貌似是个缓存,有一些热门视频。但是Android客户端常常没法拿到这个服务器,主要原因是Android客户端在获取视频地址时指定了type=mp4。如果去掉type=mp4,那获得前一个服务器的机会就大不少。 观察得知前一个服务器获得的视频基本上都是flv的。我怀疑是因为多数人使用网页版上b站,而网页版会请求flv格式,于是缓存服务器基本上也是缓存比较热门的flv格式。 其实Android客户端也可以支持flv格式的内容,因此只要把请求时候的type=mp4去掉,就更有希望获得前一个服务器上的视频。<已使用> === 优酷 === * k.youku.com ** 119.167.145.95 fast 200~2200kB/s ok 800~1100ms ** 还有很多119.167.145.* 都差不多 ** 113.103.44.51 fast ok === PPTV === 反正看不了 bc71673f7eafaeb911694d203d520d28296ddcda 419 418 2014-12-21T21:14:00Z HenryHu 1 /* 获得视频地址 */ wikitext text/x-wiki == 关于卡 == B站搞了个测试功能,于是可以观察各个源的情况。 === 获得视频地址 === 首先找interface.bilibili.com问视频在哪。目前这个请求是不加密的,有篡改的希望。或者干脆把interface.bilibili.com解析到本地,然后过滤http流量。 随后地址里的域名会被解析。这个过程是可控的。 篡改部分已经成功。 * 把interface.bilibili.com解析到192.168.1.1 * 将路由上的uhttpd换成lighttpd * 配置vhost,使得对interface.bilibili.com的请求转发到localhost:8118 <pre> $HTTP["host"] == "interface.bilibili.com" { proxy.balance = "hash" proxy.server = ( "" => ( ( "host" => "127.0.0.1" , "port" => 8118 ) ) ) } </pre> * 安装配置privoxy 本来这里的计划是用privoxy篡改请求。大概是这样: 首先加个filter: <pre> CLIENT-HEADER-FILTER: nomp4 Remove all "&type=mp4" s/&type=mp4// </pre> 然后指定action: <pre> {+client-header-filter{nomp4}} /playurl </pre> 写完之后发现,privoxy报out of memory…… 搜了一下看来是这个bug: https://dev.openwrt.org/ticket/5494 说不定新版解决了,但是我这个老路由器还是不要折腾了…… 研究发现lighttpd自己就可以rewrite,于是写了个rewrite rule * 配置lighttpd,重写请求 比如说要去掉type=mp4,可以把 <pre> url.rewrite = ( "^/(.*)&type=mp4(.*)$" => "/$1$2" ) </pre> 加在lighttpd的vhost配置里。 这样就能用了。 如果以后用SSL了,或者请求的时候检查请求校验和一类的东西了,那就没法篡改了…… === 新浪 === 新浪主要有俩域名: * v.iask.com 应该是主站吧 ** 202.108.37.55 北京 联通 ** 60.28.164.251 天津 联通 * edge.v.iask.com.lxdns.com 某CDN的节点,正规名为www.ipswitch.glb0.lxdns.com ** 121.14.35.240 广州 电信 ** 115.231.132.57 杭州 电信 ** 70.39.191.158 LA 首先是给个域名,然后从域名解析出IP。 对前一个域名,北京节点的网速比天津好多了;对后一个域名,当然是LA好。 通过在DNS上固定解析,可以绑定域名和IP。<已实行> 要固定返回的域名…… 可能要改写HTTP请求结果了。 === 乐视 === * g3.letv.cn ** 115.182.51.175 北京 (巨快) ** 117.121.54.219 北京 电信 有的其实看不了,只有广告 === B站 === * us-chicago.acgvideo.com ** 67.159.54.58 Chicago slow <100kB/s varies 700~5000ms * cc.acgvideo.com 正规名 cc00009.f.cncssr.chinacache.net ** 123.235.32.130 ** 36.250.90.194 福建省 联通 very slow <50kB/s lag >1000ms ** 182.118.9.130 河南省 联通 varies 30~300kB/s ** 221.194.130.206 河北省 联通 slow <100kB/s smooth ** 119.6.246.137 四川省 联通 very slow <50kB/s lag >1000ms ** 210.76.57.147 黑龙江 联通 very slow <50kB/s lag >1000ms ** 112.84.133.214 varies/ok 前一个貌似是个缓存,有一些热门视频。但是Android客户端常常没法拿到这个服务器,主要原因是Android客户端在获取视频地址时指定了type=mp4。如果去掉type=mp4,那获得前一个服务器的机会就大不少。 观察得知前一个服务器获得的视频基本上都是flv的。我怀疑是因为多数人使用网页版上b站,而网页版会请求flv格式,于是缓存服务器基本上也是缓存比较热门的flv格式。 其实Android客户端也可以支持flv格式的内容,因此只要把请求时候的type=mp4去掉,就更有希望获得前一个服务器上的视频。<已使用> === 优酷 === * k.youku.com ** 119.167.145.95 fast 200~2200kB/s ok 800~1100ms ** 还有很多119.167.145.* 都差不多 ** 113.103.44.51 fast ok === PPTV === 反正看不了 a83747e255d54e34bbb2f3ebd66fdeb3ed9f97a1 420 419 2014-12-21T21:16:35Z HenryHu 1 /* 优酷 */ wikitext text/x-wiki == 关于卡 == B站搞了个测试功能,于是可以观察各个源的情况。 === 获得视频地址 === 首先找interface.bilibili.com问视频在哪。目前这个请求是不加密的,有篡改的希望。或者干脆把interface.bilibili.com解析到本地,然后过滤http流量。 随后地址里的域名会被解析。这个过程是可控的。 篡改部分已经成功。 * 把interface.bilibili.com解析到192.168.1.1 * 将路由上的uhttpd换成lighttpd * 配置vhost,使得对interface.bilibili.com的请求转发到localhost:8118 <pre> $HTTP["host"] == "interface.bilibili.com" { proxy.balance = "hash" proxy.server = ( "" => ( ( "host" => "127.0.0.1" , "port" => 8118 ) ) ) } </pre> * 安装配置privoxy 本来这里的计划是用privoxy篡改请求。大概是这样: 首先加个filter: <pre> CLIENT-HEADER-FILTER: nomp4 Remove all "&type=mp4" s/&type=mp4// </pre> 然后指定action: <pre> {+client-header-filter{nomp4}} /playurl </pre> 写完之后发现,privoxy报out of memory…… 搜了一下看来是这个bug: https://dev.openwrt.org/ticket/5494 说不定新版解决了,但是我这个老路由器还是不要折腾了…… 研究发现lighttpd自己就可以rewrite,于是写了个rewrite rule * 配置lighttpd,重写请求 比如说要去掉type=mp4,可以把 <pre> url.rewrite = ( "^/(.*)&type=mp4(.*)$" => "/$1$2" ) </pre> 加在lighttpd的vhost配置里。 这样就能用了。 如果以后用SSL了,或者请求的时候检查请求校验和一类的东西了,那就没法篡改了…… === 新浪 === 新浪主要有俩域名: * v.iask.com 应该是主站吧 ** 202.108.37.55 北京 联通 ** 60.28.164.251 天津 联通 * edge.v.iask.com.lxdns.com 某CDN的节点,正规名为www.ipswitch.glb0.lxdns.com ** 121.14.35.240 广州 电信 ** 115.231.132.57 杭州 电信 ** 70.39.191.158 LA 首先是给个域名,然后从域名解析出IP。 对前一个域名,北京节点的网速比天津好多了;对后一个域名,当然是LA好。 通过在DNS上固定解析,可以绑定域名和IP。<已实行> 要固定返回的域名…… 可能要改写HTTP请求结果了。 === 乐视 === * g3.letv.cn ** 115.182.51.175 北京 (巨快) ** 117.121.54.219 北京 电信 有的其实看不了,只有广告 === B站 === * us-chicago.acgvideo.com ** 67.159.54.58 Chicago slow <100kB/s varies 700~5000ms * cc.acgvideo.com 正规名 cc00009.f.cncssr.chinacache.net ** 123.235.32.130 ** 36.250.90.194 福建省 联通 very slow <50kB/s lag >1000ms ** 182.118.9.130 河南省 联通 varies 30~300kB/s ** 221.194.130.206 河北省 联通 slow <100kB/s smooth ** 119.6.246.137 四川省 联通 very slow <50kB/s lag >1000ms ** 210.76.57.147 黑龙江 联通 very slow <50kB/s lag >1000ms ** 112.84.133.214 varies/ok 前一个貌似是个缓存,有一些热门视频。但是Android客户端常常没法拿到这个服务器,主要原因是Android客户端在获取视频地址时指定了type=mp4。如果去掉type=mp4,那获得前一个服务器的机会就大不少。 观察得知前一个服务器获得的视频基本上都是flv的。我怀疑是因为多数人使用网页版上b站,而网页版会请求flv格式,于是缓存服务器基本上也是缓存比较热门的flv格式。 其实Android客户端也可以支持flv格式的内容,因此只要把请求时候的type=mp4去掉,就更有希望获得前一个服务器上的视频。<已使用> === 优酷 === * k.youku.com ** 119.167.145.95 fast 200~2200kB/s ok 800~1100ms ** 还有很多119.167.145.* 都差不多 问题是youku有时候很贱,会返回一个redirect。redirect之后会给你一个http://<某ip>/...这样的东西 * youku redirect ** 113.103.44.51 fast ok 而且直接把某ip篡改了貌似会404,看来和后面的参数也有关系。暂时没法折腾。 === PPTV === 反正看不了 ac85d0d5f66f7b4a671f9e9513cf24ca461dd141 421 420 2014-12-21T21:17:23Z HenryHu 1 /* B站 */ wikitext text/x-wiki == 关于卡 == B站搞了个测试功能,于是可以观察各个源的情况。 === 获得视频地址 === 首先找interface.bilibili.com问视频在哪。目前这个请求是不加密的,有篡改的希望。或者干脆把interface.bilibili.com解析到本地,然后过滤http流量。 随后地址里的域名会被解析。这个过程是可控的。 篡改部分已经成功。 * 把interface.bilibili.com解析到192.168.1.1 * 将路由上的uhttpd换成lighttpd * 配置vhost,使得对interface.bilibili.com的请求转发到localhost:8118 <pre> $HTTP["host"] == "interface.bilibili.com" { proxy.balance = "hash" proxy.server = ( "" => ( ( "host" => "127.0.0.1" , "port" => 8118 ) ) ) } </pre> * 安装配置privoxy 本来这里的计划是用privoxy篡改请求。大概是这样: 首先加个filter: <pre> CLIENT-HEADER-FILTER: nomp4 Remove all "&type=mp4" s/&type=mp4// </pre> 然后指定action: <pre> {+client-header-filter{nomp4}} /playurl </pre> 写完之后发现,privoxy报out of memory…… 搜了一下看来是这个bug: https://dev.openwrt.org/ticket/5494 说不定新版解决了,但是我这个老路由器还是不要折腾了…… 研究发现lighttpd自己就可以rewrite,于是写了个rewrite rule * 配置lighttpd,重写请求 比如说要去掉type=mp4,可以把 <pre> url.rewrite = ( "^/(.*)&type=mp4(.*)$" => "/$1$2" ) </pre> 加在lighttpd的vhost配置里。 这样就能用了。 如果以后用SSL了,或者请求的时候检查请求校验和一类的东西了,那就没法篡改了…… === 新浪 === 新浪主要有俩域名: * v.iask.com 应该是主站吧 ** 202.108.37.55 北京 联通 ** 60.28.164.251 天津 联通 * edge.v.iask.com.lxdns.com 某CDN的节点,正规名为www.ipswitch.glb0.lxdns.com ** 121.14.35.240 广州 电信 ** 115.231.132.57 杭州 电信 ** 70.39.191.158 LA 首先是给个域名,然后从域名解析出IP。 对前一个域名,北京节点的网速比天津好多了;对后一个域名,当然是LA好。 通过在DNS上固定解析,可以绑定域名和IP。<已实行> 要固定返回的域名…… 可能要改写HTTP请求结果了。 === 乐视 === * g3.letv.cn ** 115.182.51.175 北京 (巨快) ** 117.121.54.219 北京 电信 有的其实看不了,只有广告 === B站 === * us-chicago.acgvideo.com ** 67.159.54.58 Chicago fast smooth <100ms * cc.acgvideo.com 正规名 cc00009.f.cncssr.chinacache.net ** 123.235.32.130 ** 36.250.90.194 福建省 联通 very slow <50kB/s lag >1000ms ** 182.118.9.130 河南省 联通 varies 30~300kB/s ** 221.194.130.206 河北省 联通 slow <100kB/s smooth ** 119.6.246.137 四川省 联通 very slow <50kB/s lag >1000ms ** 210.76.57.147 黑龙江 联通 very slow <50kB/s lag >1000ms ** 112.84.133.214 varies/ok 前一个貌似是个缓存,有一些热门视频。但是Android客户端常常没法拿到这个服务器,主要原因是Android客户端在获取视频地址时指定了type=mp4。如果去掉type=mp4,那获得前一个服务器的机会就大不少。 观察得知前一个服务器获得的视频基本上都是flv的。我怀疑是因为多数人使用网页版上b站,而网页版会请求flv格式,于是缓存服务器基本上也是缓存比较热门的flv格式。 其实Android客户端也可以支持flv格式的内容,因此只要把请求时候的type=mp4去掉,就更有希望获得前一个服务器上的视频。<已使用> === 优酷 === * k.youku.com ** 119.167.145.95 fast 200~2200kB/s ok 800~1100ms ** 还有很多119.167.145.* 都差不多 问题是youku有时候很贱,会返回一个redirect。redirect之后会给你一个http://<某ip>/...这样的东西 * youku redirect ** 113.103.44.51 fast ok 而且直接把某ip篡改了貌似会404,看来和后面的参数也有关系。暂时没法折腾。 === PPTV === 反正看不了 54ea9eb209af16b2bf6c0f412e538ab2bceb4b74 422 421 2014-12-21T21:27:51Z HenryHu 1 /* 优酷 */ wikitext text/x-wiki == 关于卡 == B站搞了个测试功能,于是可以观察各个源的情况。 === 获得视频地址 === 首先找interface.bilibili.com问视频在哪。目前这个请求是不加密的,有篡改的希望。或者干脆把interface.bilibili.com解析到本地,然后过滤http流量。 随后地址里的域名会被解析。这个过程是可控的。 篡改部分已经成功。 * 把interface.bilibili.com解析到192.168.1.1 * 将路由上的uhttpd换成lighttpd * 配置vhost,使得对interface.bilibili.com的请求转发到localhost:8118 <pre> $HTTP["host"] == "interface.bilibili.com" { proxy.balance = "hash" proxy.server = ( "" => ( ( "host" => "127.0.0.1" , "port" => 8118 ) ) ) } </pre> * 安装配置privoxy 本来这里的计划是用privoxy篡改请求。大概是这样: 首先加个filter: <pre> CLIENT-HEADER-FILTER: nomp4 Remove all "&type=mp4" s/&type=mp4// </pre> 然后指定action: <pre> {+client-header-filter{nomp4}} /playurl </pre> 写完之后发现,privoxy报out of memory…… 搜了一下看来是这个bug: https://dev.openwrt.org/ticket/5494 说不定新版解决了,但是我这个老路由器还是不要折腾了…… 研究发现lighttpd自己就可以rewrite,于是写了个rewrite rule * 配置lighttpd,重写请求 比如说要去掉type=mp4,可以把 <pre> url.rewrite = ( "^/(.*)&type=mp4(.*)$" => "/$1$2" ) </pre> 加在lighttpd的vhost配置里。 这样就能用了。 如果以后用SSL了,或者请求的时候检查请求校验和一类的东西了,那就没法篡改了…… === 新浪 === 新浪主要有俩域名: * v.iask.com 应该是主站吧 ** 202.108.37.55 北京 联通 ** 60.28.164.251 天津 联通 * edge.v.iask.com.lxdns.com 某CDN的节点,正规名为www.ipswitch.glb0.lxdns.com ** 121.14.35.240 广州 电信 ** 115.231.132.57 杭州 电信 ** 70.39.191.158 LA 首先是给个域名,然后从域名解析出IP。 对前一个域名,北京节点的网速比天津好多了;对后一个域名,当然是LA好。 通过在DNS上固定解析,可以绑定域名和IP。<已实行> 要固定返回的域名…… 可能要改写HTTP请求结果了。 === 乐视 === * g3.letv.cn ** 115.182.51.175 北京 (巨快) ** 117.121.54.219 北京 电信 有的其实看不了,只有广告 === B站 === * us-chicago.acgvideo.com ** 67.159.54.58 Chicago fast smooth <100ms * cc.acgvideo.com 正规名 cc00009.f.cncssr.chinacache.net ** 123.235.32.130 ** 36.250.90.194 福建省 联通 very slow <50kB/s lag >1000ms ** 182.118.9.130 河南省 联通 varies 30~300kB/s ** 221.194.130.206 河北省 联通 slow <100kB/s smooth ** 119.6.246.137 四川省 联通 very slow <50kB/s lag >1000ms ** 210.76.57.147 黑龙江 联通 very slow <50kB/s lag >1000ms ** 112.84.133.214 varies/ok 前一个貌似是个缓存,有一些热门视频。但是Android客户端常常没法拿到这个服务器,主要原因是Android客户端在获取视频地址时指定了type=mp4。如果去掉type=mp4,那获得前一个服务器的机会就大不少。 观察得知前一个服务器获得的视频基本上都是flv的。我怀疑是因为多数人使用网页版上b站,而网页版会请求flv格式,于是缓存服务器基本上也是缓存比较热门的flv格式。 其实Android客户端也可以支持flv格式的内容,因此只要把请求时候的type=mp4去掉,就更有希望获得前一个服务器上的视频。<已使用> === 优酷 === * k.youku.com ** 119.167.145.95 ** 还有很多119.167.145.* 都差不多 其实都是youku的前端服务器,连上会给一个redirect,给你一个http://<某ip>/...这样的东西 * youku redirect ** 113.103.44.51 mostly fast ok ** 63.243.196.190 fast 200~2200kB/s ok 800~1100ms 而且直接把某ip篡改了貌似会404,看来和后面的参数也有关系。暂时没法折腾。 === PPTV === 反正看不了 fa8a0a8a75d04f3f70544c9494f08844359dfec9 427 422 2015-02-02T04:30:31Z HenryHu 1 /* 新浪 */ wikitext text/x-wiki == 关于卡 == B站搞了个测试功能,于是可以观察各个源的情况。 === 获得视频地址 === 首先找interface.bilibili.com问视频在哪。目前这个请求是不加密的,有篡改的希望。或者干脆把interface.bilibili.com解析到本地,然后过滤http流量。 随后地址里的域名会被解析。这个过程是可控的。 篡改部分已经成功。 * 把interface.bilibili.com解析到192.168.1.1 * 将路由上的uhttpd换成lighttpd * 配置vhost,使得对interface.bilibili.com的请求转发到localhost:8118 <pre> $HTTP["host"] == "interface.bilibili.com" { proxy.balance = "hash" proxy.server = ( "" => ( ( "host" => "127.0.0.1" , "port" => 8118 ) ) ) } </pre> * 安装配置privoxy 本来这里的计划是用privoxy篡改请求。大概是这样: 首先加个filter: <pre> CLIENT-HEADER-FILTER: nomp4 Remove all "&type=mp4" s/&type=mp4// </pre> 然后指定action: <pre> {+client-header-filter{nomp4}} /playurl </pre> 写完之后发现,privoxy报out of memory…… 搜了一下看来是这个bug: https://dev.openwrt.org/ticket/5494 说不定新版解决了,但是我这个老路由器还是不要折腾了…… 研究发现lighttpd自己就可以rewrite,于是写了个rewrite rule * 配置lighttpd,重写请求 比如说要去掉type=mp4,可以把 <pre> url.rewrite = ( "^/(.*)&type=mp4(.*)$" => "/$1$2" ) </pre> 加在lighttpd的vhost配置里。 这样就能用了。 如果以后用SSL了,或者请求的时候检查请求校验和一类的东西了,那就没法篡改了…… === 新浪 === 新浪主要有俩域名: * v.iask.com 应该是主站吧 ** 202.108.37.55 北京 联通 ** 60.28.164.251 天津 联通 * edge.v.iask.com.lxdns.com 某CDN的节点,正规名为www.ipswitch.glb0.lxdns.com ** 121.14.35.240 广州 电信 ** 115.231.132.57 杭州 电信 ** 70.39.191.158 LA 首先是给个域名,然后从域名解析出IP。 对前一个域名,北京节点的网速比天津好多了;对后一个域名,当然是LA好。 通过在DNS上固定解析,可以绑定域名和IP。<已实行> 要固定返回的域名…… 可能要改写HTTP请求结果了。 ==== 再次重定向 ==== 某日发现某视频又很卡,抓包得到如下结果,是本机和70.39.191.158 port 80的交流: GET /71186550.hlv?KID=sina,viask.... HTTP/1.1 Host: edge.v.iask.com.lxdns.com .... HTTP/1.0 302 Found Cache-Control: no-cache Connection: close Location: http://8.37.235.12/edge.v.iask.com/71186550.hlv?KID=sina,viask&....&wshc_tag=1&wsts_tag=54cefbf7&wsid_tag=a0272e12&wsiphost=ipdbm 所以说看来这个cdn又重定向到了别人那里…… 这个Location后面的IP会变,返回的大概在8.37.234.x - 8.37.236.x范围里。有些IP的连接情况很糟糕,时不时丢包,甚至一个包都没有…… 有些就很靠谱…… 计划篡改这个IP,篡改到靠谱的IP上去…… === 乐视 === * g3.letv.cn ** 115.182.51.175 北京 (巨快) ** 117.121.54.219 北京 电信 有的其实看不了,只有广告 === B站 === * us-chicago.acgvideo.com ** 67.159.54.58 Chicago fast smooth <100ms * cc.acgvideo.com 正规名 cc00009.f.cncssr.chinacache.net ** 123.235.32.130 ** 36.250.90.194 福建省 联通 very slow <50kB/s lag >1000ms ** 182.118.9.130 河南省 联通 varies 30~300kB/s ** 221.194.130.206 河北省 联通 slow <100kB/s smooth ** 119.6.246.137 四川省 联通 very slow <50kB/s lag >1000ms ** 210.76.57.147 黑龙江 联通 very slow <50kB/s lag >1000ms ** 112.84.133.214 varies/ok 前一个貌似是个缓存,有一些热门视频。但是Android客户端常常没法拿到这个服务器,主要原因是Android客户端在获取视频地址时指定了type=mp4。如果去掉type=mp4,那获得前一个服务器的机会就大不少。 观察得知前一个服务器获得的视频基本上都是flv的。我怀疑是因为多数人使用网页版上b站,而网页版会请求flv格式,于是缓存服务器基本上也是缓存比较热门的flv格式。 其实Android客户端也可以支持flv格式的内容,因此只要把请求时候的type=mp4去掉,就更有希望获得前一个服务器上的视频。<已使用> === 优酷 === * k.youku.com ** 119.167.145.95 ** 还有很多119.167.145.* 都差不多 其实都是youku的前端服务器,连上会给一个redirect,给你一个http://<某ip>/...这样的东西 * youku redirect ** 113.103.44.51 mostly fast ok ** 63.243.196.190 fast 200~2200kB/s ok 800~1100ms 而且直接把某ip篡改了貌似会404,看来和后面的参数也有关系。暂时没法折腾。 === PPTV === 反正看不了 0e8e67836cfe57d088c350caa0a4c0b55f3989b6 428 427 2015-02-02T04:30:56Z HenryHu 1 /* 再次重定向 */ wikitext text/x-wiki == 关于卡 == B站搞了个测试功能,于是可以观察各个源的情况。 === 获得视频地址 === 首先找interface.bilibili.com问视频在哪。目前这个请求是不加密的,有篡改的希望。或者干脆把interface.bilibili.com解析到本地,然后过滤http流量。 随后地址里的域名会被解析。这个过程是可控的。 篡改部分已经成功。 * 把interface.bilibili.com解析到192.168.1.1 * 将路由上的uhttpd换成lighttpd * 配置vhost,使得对interface.bilibili.com的请求转发到localhost:8118 <pre> $HTTP["host"] == "interface.bilibili.com" { proxy.balance = "hash" proxy.server = ( "" => ( ( "host" => "127.0.0.1" , "port" => 8118 ) ) ) } </pre> * 安装配置privoxy 本来这里的计划是用privoxy篡改请求。大概是这样: 首先加个filter: <pre> CLIENT-HEADER-FILTER: nomp4 Remove all "&type=mp4" s/&type=mp4// </pre> 然后指定action: <pre> {+client-header-filter{nomp4}} /playurl </pre> 写完之后发现,privoxy报out of memory…… 搜了一下看来是这个bug: https://dev.openwrt.org/ticket/5494 说不定新版解决了,但是我这个老路由器还是不要折腾了…… 研究发现lighttpd自己就可以rewrite,于是写了个rewrite rule * 配置lighttpd,重写请求 比如说要去掉type=mp4,可以把 <pre> url.rewrite = ( "^/(.*)&type=mp4(.*)$" => "/$1$2" ) </pre> 加在lighttpd的vhost配置里。 这样就能用了。 如果以后用SSL了,或者请求的时候检查请求校验和一类的东西了,那就没法篡改了…… === 新浪 === 新浪主要有俩域名: * v.iask.com 应该是主站吧 ** 202.108.37.55 北京 联通 ** 60.28.164.251 天津 联通 * edge.v.iask.com.lxdns.com 某CDN的节点,正规名为www.ipswitch.glb0.lxdns.com ** 121.14.35.240 广州 电信 ** 115.231.132.57 杭州 电信 ** 70.39.191.158 LA 首先是给个域名,然后从域名解析出IP。 对前一个域名,北京节点的网速比天津好多了;对后一个域名,当然是LA好。 通过在DNS上固定解析,可以绑定域名和IP。<已实行> 要固定返回的域名…… 可能要改写HTTP请求结果了。 ==== 再次重定向 ==== 某日发现某视频又很卡,抓包得到如下结果,是本机和70.39.191.158 port 80的交流: <pre> GET /71186550.hlv?KID=sina,viask.... HTTP/1.1 Host: edge.v.iask.com.lxdns.com .... </pre> <pre> HTTP/1.0 302 Found Cache-Control: no-cache Connection: close Location: http://8.37.235.12/edge.v.iask.com/71186550.hlv?KID=sina,viask&....&wshc_tag=1&wsts_tag=54cefbf7&wsid_tag=a0272e12&wsiphost=ipdbm </pre> 所以说看来这个cdn又重定向到了别人那里…… 这个Location后面的IP会变,返回的大概在8.37.234.x - 8.37.236.x范围里。有些IP的连接情况很糟糕,时不时丢包,甚至一个包都没有…… 有些就很靠谱…… 计划篡改这个IP,篡改到靠谱的IP上去…… === 乐视 === * g3.letv.cn ** 115.182.51.175 北京 (巨快) ** 117.121.54.219 北京 电信 有的其实看不了,只有广告 === B站 === * us-chicago.acgvideo.com ** 67.159.54.58 Chicago fast smooth <100ms * cc.acgvideo.com 正规名 cc00009.f.cncssr.chinacache.net ** 123.235.32.130 ** 36.250.90.194 福建省 联通 very slow <50kB/s lag >1000ms ** 182.118.9.130 河南省 联通 varies 30~300kB/s ** 221.194.130.206 河北省 联通 slow <100kB/s smooth ** 119.6.246.137 四川省 联通 very slow <50kB/s lag >1000ms ** 210.76.57.147 黑龙江 联通 very slow <50kB/s lag >1000ms ** 112.84.133.214 varies/ok 前一个貌似是个缓存,有一些热门视频。但是Android客户端常常没法拿到这个服务器,主要原因是Android客户端在获取视频地址时指定了type=mp4。如果去掉type=mp4,那获得前一个服务器的机会就大不少。 观察得知前一个服务器获得的视频基本上都是flv的。我怀疑是因为多数人使用网页版上b站,而网页版会请求flv格式,于是缓存服务器基本上也是缓存比较热门的flv格式。 其实Android客户端也可以支持flv格式的内容,因此只要把请求时候的type=mp4去掉,就更有希望获得前一个服务器上的视频。<已使用> === 优酷 === * k.youku.com ** 119.167.145.95 ** 还有很多119.167.145.* 都差不多 其实都是youku的前端服务器,连上会给一个redirect,给你一个http://<某ip>/...这样的东西 * youku redirect ** 113.103.44.51 mostly fast ok ** 63.243.196.190 fast 200~2200kB/s ok 800~1100ms 而且直接把某ip篡改了貌似会404,看来和后面的参数也有关系。暂时没法折腾。 === PPTV === 反正看不了 c6f81180128c5dc1db7e4fd89ee03266701122f3 429 428 2015-02-02T04:32:23Z HenryHu 1 /* 再次重定向 */ wikitext text/x-wiki == 关于卡 == B站搞了个测试功能,于是可以观察各个源的情况。 === 获得视频地址 === 首先找interface.bilibili.com问视频在哪。目前这个请求是不加密的,有篡改的希望。或者干脆把interface.bilibili.com解析到本地,然后过滤http流量。 随后地址里的域名会被解析。这个过程是可控的。 篡改部分已经成功。 * 把interface.bilibili.com解析到192.168.1.1 * 将路由上的uhttpd换成lighttpd * 配置vhost,使得对interface.bilibili.com的请求转发到localhost:8118 <pre> $HTTP["host"] == "interface.bilibili.com" { proxy.balance = "hash" proxy.server = ( "" => ( ( "host" => "127.0.0.1" , "port" => 8118 ) ) ) } </pre> * 安装配置privoxy 本来这里的计划是用privoxy篡改请求。大概是这样: 首先加个filter: <pre> CLIENT-HEADER-FILTER: nomp4 Remove all "&type=mp4" s/&type=mp4// </pre> 然后指定action: <pre> {+client-header-filter{nomp4}} /playurl </pre> 写完之后发现,privoxy报out of memory…… 搜了一下看来是这个bug: https://dev.openwrt.org/ticket/5494 说不定新版解决了,但是我这个老路由器还是不要折腾了…… 研究发现lighttpd自己就可以rewrite,于是写了个rewrite rule * 配置lighttpd,重写请求 比如说要去掉type=mp4,可以把 <pre> url.rewrite = ( "^/(.*)&type=mp4(.*)$" => "/$1$2" ) </pre> 加在lighttpd的vhost配置里。 这样就能用了。 如果以后用SSL了,或者请求的时候检查请求校验和一类的东西了,那就没法篡改了…… === 新浪 === 新浪主要有俩域名: * v.iask.com 应该是主站吧 ** 202.108.37.55 北京 联通 ** 60.28.164.251 天津 联通 * edge.v.iask.com.lxdns.com 某CDN的节点,正规名为www.ipswitch.glb0.lxdns.com ** 121.14.35.240 广州 电信 ** 115.231.132.57 杭州 电信 ** 70.39.191.158 LA 首先是给个域名,然后从域名解析出IP。 对前一个域名,北京节点的网速比天津好多了;对后一个域名,当然是LA好。 通过在DNS上固定解析,可以绑定域名和IP。<已实行> 要固定返回的域名…… 可能要改写HTTP请求结果了。 ==== 再次重定向 ==== 某日发现某视频又很卡,抓包得到如下结果,是本机和70.39.191.158 port 80的交流: <pre> GET /71186550.hlv?KID=sina,viask.... HTTP/1.1 Host: edge.v.iask.com.lxdns.com .... </pre> <pre> HTTP/1.0 302 Found Cache-Control: no-cache Connection: close Location: http://8.37.235.12/edge.v.iask.com/71186550.hlv?KID=sina,viask&....&wshc_tag=1&wsts_tag=54cefbf7&wsid_tag=a0272e12&wsiphost=ipdbm </pre> 所以说看来这个cdn又重定向到了别人那里…… 这个Location后面的IP会变,返回的大概在8.37.234.x - 8.37.236.x范围里。有些IP的连接情况很糟糕,时不时丢包,甚至一个包都没有…… 有些就很靠谱…… 靠谱的: * 8.37.235.11 不靠谱的: * 8.37.236.12 * 8.37.236.14 * 8.37.236.15 计划篡改这个IP,篡改到靠谱的IP上去…… === 乐视 === * g3.letv.cn ** 115.182.51.175 北京 (巨快) ** 117.121.54.219 北京 电信 有的其实看不了,只有广告 === B站 === * us-chicago.acgvideo.com ** 67.159.54.58 Chicago fast smooth <100ms * cc.acgvideo.com 正规名 cc00009.f.cncssr.chinacache.net ** 123.235.32.130 ** 36.250.90.194 福建省 联通 very slow <50kB/s lag >1000ms ** 182.118.9.130 河南省 联通 varies 30~300kB/s ** 221.194.130.206 河北省 联通 slow <100kB/s smooth ** 119.6.246.137 四川省 联通 very slow <50kB/s lag >1000ms ** 210.76.57.147 黑龙江 联通 very slow <50kB/s lag >1000ms ** 112.84.133.214 varies/ok 前一个貌似是个缓存,有一些热门视频。但是Android客户端常常没法拿到这个服务器,主要原因是Android客户端在获取视频地址时指定了type=mp4。如果去掉type=mp4,那获得前一个服务器的机会就大不少。 观察得知前一个服务器获得的视频基本上都是flv的。我怀疑是因为多数人使用网页版上b站,而网页版会请求flv格式,于是缓存服务器基本上也是缓存比较热门的flv格式。 其实Android客户端也可以支持flv格式的内容,因此只要把请求时候的type=mp4去掉,就更有希望获得前一个服务器上的视频。<已使用> === 优酷 === * k.youku.com ** 119.167.145.95 ** 还有很多119.167.145.* 都差不多 其实都是youku的前端服务器,连上会给一个redirect,给你一个http://<某ip>/...这样的东西 * youku redirect ** 113.103.44.51 mostly fast ok ** 63.243.196.190 fast 200~2200kB/s ok 800~1100ms 而且直接把某ip篡改了貌似会404,看来和后面的参数也有关系。暂时没法折腾。 === PPTV === 反正看不了 67253da0a9d2bd1f9923f173281860fd4bcbbe99 431 429 2015-02-09T02:39:43Z HenryHu 1 /* 再次重定向 */ wikitext text/x-wiki == 关于卡 == B站搞了个测试功能,于是可以观察各个源的情况。 === 获得视频地址 === 首先找interface.bilibili.com问视频在哪。目前这个请求是不加密的,有篡改的希望。或者干脆把interface.bilibili.com解析到本地,然后过滤http流量。 随后地址里的域名会被解析。这个过程是可控的。 篡改部分已经成功。 * 把interface.bilibili.com解析到192.168.1.1 * 将路由上的uhttpd换成lighttpd * 配置vhost,使得对interface.bilibili.com的请求转发到localhost:8118 <pre> $HTTP["host"] == "interface.bilibili.com" { proxy.balance = "hash" proxy.server = ( "" => ( ( "host" => "127.0.0.1" , "port" => 8118 ) ) ) } </pre> * 安装配置privoxy 本来这里的计划是用privoxy篡改请求。大概是这样: 首先加个filter: <pre> CLIENT-HEADER-FILTER: nomp4 Remove all "&type=mp4" s/&type=mp4// </pre> 然后指定action: <pre> {+client-header-filter{nomp4}} /playurl </pre> 写完之后发现,privoxy报out of memory…… 搜了一下看来是这个bug: https://dev.openwrt.org/ticket/5494 说不定新版解决了,但是我这个老路由器还是不要折腾了…… 研究发现lighttpd自己就可以rewrite,于是写了个rewrite rule * 配置lighttpd,重写请求 比如说要去掉type=mp4,可以把 <pre> url.rewrite = ( "^/(.*)&type=mp4(.*)$" => "/$1$2" ) </pre> 加在lighttpd的vhost配置里。 这样就能用了。 如果以后用SSL了,或者请求的时候检查请求校验和一类的东西了,那就没法篡改了…… === 新浪 === 新浪主要有俩域名: * v.iask.com 应该是主站吧 ** 202.108.37.55 北京 联通 ** 60.28.164.251 天津 联通 * edge.v.iask.com.lxdns.com 某CDN的节点,正规名为www.ipswitch.glb0.lxdns.com ** 121.14.35.240 广州 电信 ** 115.231.132.57 杭州 电信 ** 70.39.191.158 LA 首先是给个域名,然后从域名解析出IP。 对前一个域名,北京节点的网速比天津好多了;对后一个域名,当然是LA好。 通过在DNS上固定解析,可以绑定域名和IP。<已实行> 要固定返回的域名…… 可能要改写HTTP请求结果了。 ==== 再次重定向 ==== 某日发现某视频又很卡,抓包得到如下结果,是本机和70.39.191.158 port 80的交流: <pre> GET /71186550.hlv?KID=sina,viask.... HTTP/1.1 Host: edge.v.iask.com.lxdns.com .... </pre> <pre> HTTP/1.0 302 Found Cache-Control: no-cache Connection: close Location: http://8.37.235.12/edge.v.iask.com/71186550.hlv?KID=sina,viask&....&wshc_tag=1&wsts_tag=54cefbf7&wsid_tag=a0272e12&wsiphost=ipdbm </pre> 所以说看来这个cdn又重定向到了别人那里…… 这个Location后面的IP会变,返回的大概在8.37.233.x - 8.37.236.x范围里。有些IP的连接情况很糟糕,时不时丢包,甚至一个包都没有…… 有些就很靠谱…… 靠谱的: * 8.37.235.11 不靠谱的: * 8.37.233.16 * 8.37.236.12 * 8.37.236.14 * 8.37.236.15 计划篡改这个IP,篡改到靠谱的IP上去…… [已实行] === 乐视 === * g3.letv.cn ** 115.182.51.175 北京 (巨快) ** 117.121.54.219 北京 电信 有的其实看不了,只有广告 === B站 === * us-chicago.acgvideo.com ** 67.159.54.58 Chicago fast smooth <100ms * cc.acgvideo.com 正规名 cc00009.f.cncssr.chinacache.net ** 123.235.32.130 ** 36.250.90.194 福建省 联通 very slow <50kB/s lag >1000ms ** 182.118.9.130 河南省 联通 varies 30~300kB/s ** 221.194.130.206 河北省 联通 slow <100kB/s smooth ** 119.6.246.137 四川省 联通 very slow <50kB/s lag >1000ms ** 210.76.57.147 黑龙江 联通 very slow <50kB/s lag >1000ms ** 112.84.133.214 varies/ok 前一个貌似是个缓存,有一些热门视频。但是Android客户端常常没法拿到这个服务器,主要原因是Android客户端在获取视频地址时指定了type=mp4。如果去掉type=mp4,那获得前一个服务器的机会就大不少。 观察得知前一个服务器获得的视频基本上都是flv的。我怀疑是因为多数人使用网页版上b站,而网页版会请求flv格式,于是缓存服务器基本上也是缓存比较热门的flv格式。 其实Android客户端也可以支持flv格式的内容,因此只要把请求时候的type=mp4去掉,就更有希望获得前一个服务器上的视频。<已使用> === 优酷 === * k.youku.com ** 119.167.145.95 ** 还有很多119.167.145.* 都差不多 其实都是youku的前端服务器,连上会给一个redirect,给你一个http://<某ip>/...这样的东西 * youku redirect ** 113.103.44.51 mostly fast ok ** 63.243.196.190 fast 200~2200kB/s ok 800~1100ms 而且直接把某ip篡改了貌似会404,看来和后面的参数也有关系。暂时没法折腾。 === PPTV === 反正看不了 43ba4e05e9ca84dca4ba446fc45ef32355865de6 432 431 2015-02-09T02:44:05Z HenryHu 1 /* 获得视频地址 */ wikitext text/x-wiki == 关于卡 == B站搞了个测试功能,于是可以观察各个源的情况。 === 获得视频地址 === 首先找interface.bilibili.com问视频在哪。目前这个请求是不加密的,有篡改的希望。或者干脆把interface.bilibili.com解析到本地,然后过滤http流量。 随后地址里的域名会被解析。这个过程是可控的。 === 篡改请求内容 === 篡改部分已经成功。 * 把interface.bilibili.com解析到192.168.1.1 * 将路由上的uhttpd换成lighttpd * 配置vhost,使得对interface.bilibili.com的请求转发到localhost:8118 <pre> $HTTP["host"] == "interface.bilibili.com" { proxy.balance = "hash" proxy.server = ( "" => ( ( "host" => "127.0.0.1" , "port" => 8118 ) ) ) } </pre> * 安装配置privoxy 本来这里的计划是用privoxy篡改请求。大概是这样: 首先加个filter: <pre> CLIENT-HEADER-FILTER: nomp4 Remove all "&type=mp4" s/&type=mp4// </pre> 然后指定action: <pre> {+client-header-filter{nomp4}} /playurl </pre> 写完之后发现,privoxy报out of memory…… 搜了一下看来是这个bug: https://dev.openwrt.org/ticket/5494 说不定新版解决了,但是我这个老路由器还是不要折腾了…… 研究发现lighttpd自己就可以rewrite,于是写了个rewrite rule * 配置lighttpd,重写请求 比如说要去掉type=mp4,可以把 <pre> url.rewrite = ( "^/(.*)&type=mp4(.*)$" => "/$1$2" ) </pre> 加在lighttpd的vhost配置里。 这样就能用了。 如果以后用SSL了,或者请求的时候检查请求校验和一类的东西了,那就没法篡改了…… === 篡改重定向结果 === 在有privoxy的情况下,首先在lighthttpd配置好伪服务器: $HTTP["host"] == "edge.v.iask.com.lxdns.com" { proxy.server = ( "" => ( ( "host" => "127.0.0.1", "port" => 8118 ) ) ) } 其次让edge.v.iask.com.lxdns.com解析为192.168.1.1,这样对它的请求就重定向到privoxy了。 然后在privoxy里,先加上要干的事情:修改user.filter,加 <pre> SERVER-HEADER-FILTER: lxdns-redirect Redirect to some better servers s@^(Location:)\s*http://8.37.23[0-9.]+/(.*)$@$1 http://8.37.235.11/$2@i </pre> 大体上就是说,匹配服务器返回的header里面的Location header,篡改其服务器部分。 其次,说好啥时候用这个rule。修改user.action,加 <pre> {+server-header-filter{lxdns-redirect}} edge.v.iask.com.lxdns.com/.* </pre> 就是说在匹配edge.v.xxx的时候用那个filter。 最后把这俩文件加进privoxy的配置文件,就可以了…… === 新浪 === 新浪主要有俩域名: * v.iask.com 应该是主站吧 ** 202.108.37.55 北京 联通 ** 60.28.164.251 天津 联通 * edge.v.iask.com.lxdns.com 某CDN的节点,正规名为www.ipswitch.glb0.lxdns.com ** 121.14.35.240 广州 电信 ** 115.231.132.57 杭州 电信 ** 70.39.191.158 LA 首先是给个域名,然后从域名解析出IP。 对前一个域名,北京节点的网速比天津好多了;对后一个域名,当然是LA好。 通过在DNS上固定解析,可以绑定域名和IP。<已实行> 要固定返回的域名…… 可能要改写HTTP请求结果了。 ==== 再次重定向 ==== 某日发现某视频又很卡,抓包得到如下结果,是本机和70.39.191.158 port 80的交流: <pre> GET /71186550.hlv?KID=sina,viask.... HTTP/1.1 Host: edge.v.iask.com.lxdns.com .... </pre> <pre> HTTP/1.0 302 Found Cache-Control: no-cache Connection: close Location: http://8.37.235.12/edge.v.iask.com/71186550.hlv?KID=sina,viask&....&wshc_tag=1&wsts_tag=54cefbf7&wsid_tag=a0272e12&wsiphost=ipdbm </pre> 所以说看来这个cdn又重定向到了别人那里…… 这个Location后面的IP会变,返回的大概在8.37.233.x - 8.37.236.x范围里。有些IP的连接情况很糟糕,时不时丢包,甚至一个包都没有…… 有些就很靠谱…… 靠谱的: * 8.37.235.11 不靠谱的: * 8.37.233.16 * 8.37.236.12 * 8.37.236.14 * 8.37.236.15 计划篡改这个IP,篡改到靠谱的IP上去…… [已实行] === 乐视 === * g3.letv.cn ** 115.182.51.175 北京 (巨快) ** 117.121.54.219 北京 电信 有的其实看不了,只有广告 === B站 === * us-chicago.acgvideo.com ** 67.159.54.58 Chicago fast smooth <100ms * cc.acgvideo.com 正规名 cc00009.f.cncssr.chinacache.net ** 123.235.32.130 ** 36.250.90.194 福建省 联通 very slow <50kB/s lag >1000ms ** 182.118.9.130 河南省 联通 varies 30~300kB/s ** 221.194.130.206 河北省 联通 slow <100kB/s smooth ** 119.6.246.137 四川省 联通 very slow <50kB/s lag >1000ms ** 210.76.57.147 黑龙江 联通 very slow <50kB/s lag >1000ms ** 112.84.133.214 varies/ok 前一个貌似是个缓存,有一些热门视频。但是Android客户端常常没法拿到这个服务器,主要原因是Android客户端在获取视频地址时指定了type=mp4。如果去掉type=mp4,那获得前一个服务器的机会就大不少。 观察得知前一个服务器获得的视频基本上都是flv的。我怀疑是因为多数人使用网页版上b站,而网页版会请求flv格式,于是缓存服务器基本上也是缓存比较热门的flv格式。 其实Android客户端也可以支持flv格式的内容,因此只要把请求时候的type=mp4去掉,就更有希望获得前一个服务器上的视频。<已使用> === 优酷 === * k.youku.com ** 119.167.145.95 ** 还有很多119.167.145.* 都差不多 其实都是youku的前端服务器,连上会给一个redirect,给你一个http://<某ip>/...这样的东西 * youku redirect ** 113.103.44.51 mostly fast ok ** 63.243.196.190 fast 200~2200kB/s ok 800~1100ms 而且直接把某ip篡改了貌似会404,看来和后面的参数也有关系。暂时没法折腾。 === PPTV === 反正看不了 2cb520e242e6ec394203bcba1dda144025a1d22a 433 432 2015-02-09T02:45:07Z HenryHu 1 /* 篡改重定向结果 */ wikitext text/x-wiki == 关于卡 == B站搞了个测试功能,于是可以观察各个源的情况。 === 获得视频地址 === 首先找interface.bilibili.com问视频在哪。目前这个请求是不加密的,有篡改的希望。或者干脆把interface.bilibili.com解析到本地,然后过滤http流量。 随后地址里的域名会被解析。这个过程是可控的。 === 篡改请求内容 === 篡改部分已经成功。 * 把interface.bilibili.com解析到192.168.1.1 * 将路由上的uhttpd换成lighttpd * 配置vhost,使得对interface.bilibili.com的请求转发到localhost:8118 <pre> $HTTP["host"] == "interface.bilibili.com" { proxy.balance = "hash" proxy.server = ( "" => ( ( "host" => "127.0.0.1" , "port" => 8118 ) ) ) } </pre> * 安装配置privoxy 本来这里的计划是用privoxy篡改请求。大概是这样: 首先加个filter: <pre> CLIENT-HEADER-FILTER: nomp4 Remove all "&type=mp4" s/&type=mp4// </pre> 然后指定action: <pre> {+client-header-filter{nomp4}} /playurl </pre> 写完之后发现,privoxy报out of memory…… 搜了一下看来是这个bug: https://dev.openwrt.org/ticket/5494 说不定新版解决了,但是我这个老路由器还是不要折腾了…… 研究发现lighttpd自己就可以rewrite,于是写了个rewrite rule * 配置lighttpd,重写请求 比如说要去掉type=mp4,可以把 <pre> url.rewrite = ( "^/(.*)&type=mp4(.*)$" => "/$1$2" ) </pre> 加在lighttpd的vhost配置里。 这样就能用了。 如果以后用SSL了,或者请求的时候检查请求校验和一类的东西了,那就没法篡改了…… === 篡改重定向结果 === 在有privoxy的情况下,首先在lighthttpd配置好伪服务器: <pre> $HTTP["host"] == "edge.v.iask.com.lxdns.com" { proxy.server = ( "" => ( ( "host" => "127.0.0.1", "port" => 8118 ) ) ) } </pre> 其次让edge.v.iask.com.lxdns.com解析为192.168.1.1,这样对它的请求就重定向到privoxy了。 然后在privoxy里,先加上要干的事情:修改user.filter,加 <pre> SERVER-HEADER-FILTER: lxdns-redirect Redirect to some better servers s@^(Location:)\s*http://8.37.23[0-9.]+/(.*)$@$1 http://8.37.235.11/$2@i </pre> 大体上就是说,匹配服务器返回的header里面的Location header,篡改其服务器部分。 其次,说好啥时候用这个rule。修改user.action,加 <pre> {+server-header-filter{lxdns-redirect}} edge.v.iask.com.lxdns.com/.* </pre> 就是说在匹配edge.v.xxx的时候用那个filter。 最后把这俩文件加进privoxy的配置文件,就可以了…… === 新浪 === 新浪主要有俩域名: * v.iask.com 应该是主站吧 ** 202.108.37.55 北京 联通 ** 60.28.164.251 天津 联通 * edge.v.iask.com.lxdns.com 某CDN的节点,正规名为www.ipswitch.glb0.lxdns.com ** 121.14.35.240 广州 电信 ** 115.231.132.57 杭州 电信 ** 70.39.191.158 LA 首先是给个域名,然后从域名解析出IP。 对前一个域名,北京节点的网速比天津好多了;对后一个域名,当然是LA好。 通过在DNS上固定解析,可以绑定域名和IP。<已实行> 要固定返回的域名…… 可能要改写HTTP请求结果了。 ==== 再次重定向 ==== 某日发现某视频又很卡,抓包得到如下结果,是本机和70.39.191.158 port 80的交流: <pre> GET /71186550.hlv?KID=sina,viask.... HTTP/1.1 Host: edge.v.iask.com.lxdns.com .... </pre> <pre> HTTP/1.0 302 Found Cache-Control: no-cache Connection: close Location: http://8.37.235.12/edge.v.iask.com/71186550.hlv?KID=sina,viask&....&wshc_tag=1&wsts_tag=54cefbf7&wsid_tag=a0272e12&wsiphost=ipdbm </pre> 所以说看来这个cdn又重定向到了别人那里…… 这个Location后面的IP会变,返回的大概在8.37.233.x - 8.37.236.x范围里。有些IP的连接情况很糟糕,时不时丢包,甚至一个包都没有…… 有些就很靠谱…… 靠谱的: * 8.37.235.11 不靠谱的: * 8.37.233.16 * 8.37.236.12 * 8.37.236.14 * 8.37.236.15 计划篡改这个IP,篡改到靠谱的IP上去…… [已实行] === 乐视 === * g3.letv.cn ** 115.182.51.175 北京 (巨快) ** 117.121.54.219 北京 电信 有的其实看不了,只有广告 === B站 === * us-chicago.acgvideo.com ** 67.159.54.58 Chicago fast smooth <100ms * cc.acgvideo.com 正规名 cc00009.f.cncssr.chinacache.net ** 123.235.32.130 ** 36.250.90.194 福建省 联通 very slow <50kB/s lag >1000ms ** 182.118.9.130 河南省 联通 varies 30~300kB/s ** 221.194.130.206 河北省 联通 slow <100kB/s smooth ** 119.6.246.137 四川省 联通 very slow <50kB/s lag >1000ms ** 210.76.57.147 黑龙江 联通 very slow <50kB/s lag >1000ms ** 112.84.133.214 varies/ok 前一个貌似是个缓存,有一些热门视频。但是Android客户端常常没法拿到这个服务器,主要原因是Android客户端在获取视频地址时指定了type=mp4。如果去掉type=mp4,那获得前一个服务器的机会就大不少。 观察得知前一个服务器获得的视频基本上都是flv的。我怀疑是因为多数人使用网页版上b站,而网页版会请求flv格式,于是缓存服务器基本上也是缓存比较热门的flv格式。 其实Android客户端也可以支持flv格式的内容,因此只要把请求时候的type=mp4去掉,就更有希望获得前一个服务器上的视频。<已使用> === 优酷 === * k.youku.com ** 119.167.145.95 ** 还有很多119.167.145.* 都差不多 其实都是youku的前端服务器,连上会给一个redirect,给你一个http://<某ip>/...这样的东西 * youku redirect ** 113.103.44.51 mostly fast ok ** 63.243.196.190 fast 200~2200kB/s ok 800~1100ms 而且直接把某ip篡改了貌似会404,看来和后面的参数也有关系。暂时没法折腾。 === PPTV === 反正看不了 61a8a7f1a1291b3bcda9776a7eccbb373d4cea63 BBS数据接口 0 76 423 382 2014-12-22T21:08:23Z HenryHu 1 /* 编辑 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <string: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>}, "group": <int: Group ID, or 0 if not in a group, match with id>, "isdir": <boolean: is a board group> [optional], "child_count": <int: children count of the board group> [optional] } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |- | group || int || Board group to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 获取同主题帖子列表 === : '''GET''' /board/thread_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || how detailed the result should be || Yes || '''idonly'''/compact/detailed |- | start || int || where to start the listing || Yes || |- | count || int || how many posts to list || Yes || |- | tid || int || id of the thread to list || No || |- | max_lines || int || (only in detailed mode) max number of lines to return || Yes || |} * Return value ** mode == idonly: ** <source lang="javascript"> { result: 'ok', list: [ { id: <int: post id>, xid: <int: unique post id> }, ... ] } </source> ** mode == compact / detailed: <source lang="javascript"> { result: 'ok', list: [ <same as /post/view>, ... ] } </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g, deletable PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional || Choices |- | session || string || Session Token || No || |- | id || int || ID of the post in this board || No || |- | board || string || Name of the board this post belongs to || No || |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | start || int || Start from line No. || Yes || start >= 0 |- | count || int || Lines to fetch || Yes || count >= 0 |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |- | mode || string || how detailed the result should be || Yes || '''idonly'''/compact/detailed |- | max_lines || int || (only when mode=detailed) number of lines to return || Yes || |} * Result ** If mode = idonly: ** {'nextid': <int: next post id in the thread>, 'nextxid': <int: next post's unique id>} ** If mode = compact/detailed: same as the result of /post/view * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 === 删帖 === : '''POST''' /post/delete {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to delete || Yes || |- | xid || int || unique ID of the post to delete || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以删自己的贴,版主可以删别人的贴。 === 编辑 === : '''POST''' /post/edit {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to edit || Yes || |- | xid || int || unique ID of the post to edit || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |- | title || string || new title || Yes || 如果没有则不变 |- | content || string || new content || Yes || 如果没有则不变 |- | new_attachments || string || JSON encoded PostAttachInfo || Yes || 新的附件列表,参见发贴 |- | del_attachments || array<int> || attachments to remove || Yes || 要删除的附件编号,从0开始 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以编辑自己的贴,版主可以编辑别人的贴。 === 搜索 === : '''GET''' /post/search {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | from || int || search from this post || Yes || 默认从头开始 |- | forward || int || search forward || Yes || 0/1,默认向前搜索(1) |- | count || int || max number of search results || Yes || 默认返回一个结果 |- | query || JSON of search query || search query || No || 格式参见下文 |} query是一个表达式,基本形式为: [<op>, <arg1>, <arg2>, ...] 其中op为操作符。目前支持: * 逻辑操作符,每个参数都是一个表达式 ** or: 取所有参数结果的或 ** and: 取所有参数结果的与 ** not: 取所有参数结果的非,只能有一个参数 ** 样例 *** ['or', <expr1>, <expr2>, <expr3>] *** ['not', <expr>] * 字符串域匹配,有一个参数,为一个正则表达式 ** author: 匹配作者 ** title: 匹配标题 ** content: 匹配内容 ** 样例 *** ['author', 'henryhu'] *** ['title', 'hell.+orld'] * 标记匹配,没有参数 ** m: 被m帖子 ** g: 收精帖子 ** noreply: 不可回复帖子 ** has_attach: 有附件 ** 样例: ['m'] * 整数域匹配,第一个参数为域名,第二个参数为比较值 ** 操作符 *** ge: 大于等于 *** le: 小于等于 *** eq: 等于 ** 域名 *** posttime: 发帖时间 *** thread: 主题编号,主题贴xid *** size: 帖子大小 ** 样例 *** ['ge', 'posttime', <time, UTC+8 seconds>] *** ['eq', 'thread', 1234] == 收藏夹 == FavBoardEntry: <source lang="javascript"> { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard, -1 for root entry>, "type": <string: Type of this entry, "board"/"dir"> } </source> === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first entry to list || Yes |- | end || int || ID of the last entry to list || Yes |- | count || int || Number of entries to list || Yes |} * Return value ** Success: <source lang="javascript"> [ FavBoardEntry, ... ] </source> === 列出某个项目的所有祖先项目 === : '''GET''' /favboard/dirnames {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | index || int || Index of the entry || No |} * Return value ** Success: <source lang="javascript"> [ FavBoardEntry, // the current entry FavBoardEntry, // its father FavBoardEntry, // its grandfather ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, <*PostContent: content of the post>, 'attachlink': <string: URL of the page showing attachments. add '&a=offset' for individual attachment> } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> === 注册新用户 === : '''POST''' /user/register {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | username || string || User ID || No |- | password || string || Password || No |- | nick || string || Nick name || No |- | email || string || Email || No |- | realname || string || Real name || No |- | address || string || Address || No |- | birthyear || int || Birth year || No |- | birthmonth || int || Birth month || No |- | birthday || int || Birth day || No |- | gender || string || Gender (F/M) || No |- | selfintro || string || Self Introduction || Yes |- | phone || string || Contact information || No |- | career || string || Class information || No |} * Return value: <source lang="javascript"> {"result": "ok"} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> === 引用邮件 === : '''GET''' /mail/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || the folder of the quoted mail || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |- | mode || string || quote mode, same as post/quote || yes || '''S'''/R/N/A |} * Return value: <source lang="javascript"> { "title": <string: quoted title>, "content": <string: quoted content> } </source> 引用某个邮件箱里的某封邮件,可选引用模式。 === 发邮件 === : '''POST''' /mail/send {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | to || string || receiver id || no || |- | title || string || mail title || no || |- | content || string || mail content || no || |- | signature_id || int || signature id || yes || '''0(none)'''/-1(random)/>0 |- | save_in_sent || int || save the mail in the sent box || yes || '''1'''/0 |} * Return value: <source lang="javascript"> {"result": "ok"} </source> 发邮件,可选是否存发件箱。 如果需要引用邮件,请先调用/mail/quote。 f6a9d0444348f29b918e5e1523ee272899705364 424 423 2014-12-22T21:08:55Z HenryHu 1 /* 编辑 */ wikitext text/x-wiki == 数据类型 == AttachInfo: <source lang="javascript"> { "name": <string: Attachment filename>, "offset:": <int: Attachment offset in post> } </source> == JSONP == {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | jsonp || string || JSONP function name || Yes |- | jsoncallback || string || JSONP function name || Yes |} If you want JSONP, just add '''jsonp=function''', and the result would be <source lang='javascript'> function(data); </source> == 登录 == [[BBS OAuth]] == 版面 == BoardInfo: <source lang="javascript"> { "name": <string: Board name>, "read": <Boolean: Board read?>, "BM": <string: BMs>, "id": <int: Board id>, "total": <int: Total post count>, "currentusers": <int: Current users count>, "major": <string: major class>, "minor": <string: minor class>, "outpost": <string: may outpost>, "desc": <string: description>}, "group": <int: Group ID, or 0 if not in a group, match with id>, "isdir": <boolean: is a board group> [optional], "child_count": <int: children count of the board group> [optional] } </source> * 帖子列表模式(通常以mode参数出现): ** normal: 普通模式 ** digest: 文摘模式 ** mark: 被m模式 ** thread: 同主题模式 ** origin: 原作模式 ** sticky: 置顶模式 === 列出版面 === : '''GET''' /board/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |- | group || int || Board group to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <BoardInfo: information of one board>, ... ] </source> === 获取帖子列表 === : '''GET''' /board/post_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || Mode of this board to list || Yes || 帖子列表模式 |- | start || int || ID of the first post to list || Yes |- | end || int || ID of the last post to list || Yes |- | count || int || Number of posts to list || Yes |} * Return value ** Success: <source lang="javascript"> [ <PostInfo: information of one post>, ... ] </source> === 获取同主题帖子列表 === : '''GET''' /board/thread_list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | name || string || Name of the board to list || No |- | mode || string || how detailed the result should be || Yes || '''idonly'''/compact/detailed |- | start || int || where to start the listing || Yes || |- | count || int || how many posts to list || Yes || |- | tid || int || id of the thread to list || No || |- | max_lines || int || (only in detailed mode) max number of lines to return || Yes || |} * Return value ** mode == idonly: ** <source lang="javascript"> { result: 'ok', list: [ { id: <int: post id>, xid: <int: unique post id> }, ... ] } </source> ** mode == compact / detailed: <source lang="javascript"> { result: 'ok', list: [ <same as /post/view>, ... ] } </source> === 清除未读标记 === : '''POST''' /board/clear_unread {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board to list, or clear everything if ignored || Yes |- | to || int || unique ID (xid) of the post to clear to || Yes |} 如果不提供to参数,则清除所有。否则清楚从开始到指定帖子的未读标记。如果连name都不提供…… 那就清除所有版面未读标记! === 获取备忘录 === : '''GET''' /board/note {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} === 获取秘密备忘录 === : '''GET''' /board/secnote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | name || string || Name of the board || No |} == 帖子 == PostInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <Boolean: Post read>, "title": <string: Post title>, "attachment": <int: Attachment count>, "owner": <string: Poster userid>, "id": <int: Post id>, "xid": <int: unique post ID>, "thread": <int: thread ID>, "reply_to": <int: ID of the post this post replied to>, "size": <int: post size>, "flags": [<string: one flag>, ...], } </source> * flags: marked, noreply, g, deletable PostContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: Post content>, } </source> PostAttachInfo: <source lang="javascript"> [ { "name": <string: attachment file name>, "store_id": <string: ID of the storage, returned from store/new> }, ... ] </source> === 获取帖子 === : '''GET''' /post/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional || Choices |- | session || string || Session Token || No || |- | id || int || ID of the post in this board || No || |- | board || string || Name of the board this post belongs to || No || |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | start || int || Start from line No. || Yes || start >= 0 |- | count || int || Lines to fetch || Yes || count >= 0 |} * Return value ** Success: <source lang="javascript"> { "attachlink": <string: base of attachment link. add "&a=offset" to obtain the full link.>, <*PostContent: content of the post>, <*PostInfo: information of the post> } </source> === 获取附件 === : '''GET''' /post/get_attach {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | id || int || ID of the post in this board || No |- | board || string || Name of the board this post belongs to || No |- | mode || string || Mode of the board this ID corresponds to || Yes || 帖子列表模式 |- | offset || int || Offset of the attachment in the post, returned in "view" || No |} * Result value <source lang="javascript"> { "content": <string: Post content encoded in Base64>, "name": <string: Attachment name> } </source> === 同主题浏览 === : '''GET''' /post/nextid {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session token || No || |- | id || int || Post ID to start search from || No || |- | board || string || Board name || No || |- | direction || string || Search direction || Yes || '''forward'''/backward |- | last_one || bool || Search for the last post || Yes || '''0'''/1 |- | only_new || bool || Only search for new post || Yes || '''0'''/1 |- | mode || string || how detailed the result should be || Yes || '''idonly'''/compact/detailed |- | max_lines || int || (only when mode=detailed) number of lines to return || Yes || |} * Result ** If mode = idonly: ** {'nextid': <int: next post id in the thread>, 'nextxid': <int: next post's unique id>} ** If mode = compact/detailed: same as the result of /post/view * Examples ** direction=forward: search for next post in the same thread ** direction=backward, last_one=1: go to the head of the thread ** direction=backward, last_one=1, only_new=1: go to the first unread post in the thread === 引用帖子 === : '''GET''' /post/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No |- | board || string || Name of the board this post belongs to || No |- | id || int || ID of the post to quote || No |- | xid || int || unique ID of the post to quote || No |- | mode || string || quote mode || Yes || '''S'''/R/N/A |- | index_mode || string || mode of the post list where ID belongs to || Yes || 帖子列表模式 |} * Result ** <source lang="javascript">{"title": <string: Quoted title>, "content": <string: Quoted content>}</source> === 准备 === : '''GET''' /post/prepare {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | for || string || action to prepare for || No || new |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply (for=new) || Yes || |- | re_xid || int || unique ID of the post to reply (for=new) || Yes || |- | re_mode || string || mode of the post list where re_id belongs to (for=new) || Yes || 帖子列表模式 |- | anonymous || boolean || create anonymous post (for=new) || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} result: <source lang="javascript">{"error": {<string: error>: 1}}</source> 如果没错误,那后面的hash是空的。 === 发帖/回帖 === : '''POST''' /post/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | re_id || int || ID of the post to reply || Yes || |- | re_xid || int || unique ID of the post to reply || Yes || |- | re_mode || string || mode of the post list where re_id belongs to || Yes || 帖子列表模式 |- | title || string || title of the post || No || |- | content || string || content of the post || No || |- | signature_id || int || No. of qmd to use || Yes || <0(random)/'''0'''(none)/>0(qmd #) |- | anonymous || boolean || create anonymous post || Yes || '''0'''(no)/1(yes) |- | mailback || boolean || require replies to be mailed back || Yes || '''0'''(no)/1(yes) |- | attachments || JSON encoded PostAttachInfo || attachments info || Yes || |} 发帖的话,id和xid可以忽略。回帖的话,需要提供id和xid。 === 删帖 === : '''POST''' /post/delete {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to delete || Yes || |- | xid || int || unique ID of the post to delete || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以删自己的贴,版主可以删别人的贴。 === 编辑 === : '''POST''' /post/edit {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | id || int || ID of the post to edit || Yes || |- | xid || int || unique ID of the post to edit || No || |- | mode || string || mode of the post list where id belongs to || Yes || 帖子列表模式 |- | title || string || new title || Yes || 如果没有则不变 |- | content || string || new content || Yes || 如果没有则不变 |- | new_attachments || JSON encoded PostAttachInfo || new attachments info || Yes || 新的附件列表,参见发贴 |- | del_attachments || array<int> || attachments to remove || Yes || 要删除的附件编号,从0开始 |} xid是必须的,用于唯一定位帖子。id不是必需的。 每个人可以编辑自己的贴,版主可以编辑别人的贴。 === 搜索 === : '''GET''' /post/search {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | board || string || Name of the board this post belongs to || No || |- | from || int || search from this post || Yes || 默认从头开始 |- | forward || int || search forward || Yes || 0/1,默认向前搜索(1) |- | count || int || max number of search results || Yes || 默认返回一个结果 |- | query || JSON of search query || search query || No || 格式参见下文 |} query是一个表达式,基本形式为: [<op>, <arg1>, <arg2>, ...] 其中op为操作符。目前支持: * 逻辑操作符,每个参数都是一个表达式 ** or: 取所有参数结果的或 ** and: 取所有参数结果的与 ** not: 取所有参数结果的非,只能有一个参数 ** 样例 *** ['or', <expr1>, <expr2>, <expr3>] *** ['not', <expr>] * 字符串域匹配,有一个参数,为一个正则表达式 ** author: 匹配作者 ** title: 匹配标题 ** content: 匹配内容 ** 样例 *** ['author', 'henryhu'] *** ['title', 'hell.+orld'] * 标记匹配,没有参数 ** m: 被m帖子 ** g: 收精帖子 ** noreply: 不可回复帖子 ** has_attach: 有附件 ** 样例: ['m'] * 整数域匹配,第一个参数为域名,第二个参数为比较值 ** 操作符 *** ge: 大于等于 *** le: 小于等于 *** eq: 等于 ** 域名 *** posttime: 发帖时间 *** thread: 主题编号,主题贴xid *** size: 帖子大小 ** 样例 *** ['ge', 'posttime', <time, UTC+8 seconds>] *** ['eq', 'thread', 1234] == 收藏夹 == FavBoardEntry: <source lang="javascript"> { "index": <int: Index in favboard>, "binfo": <BoardInfo: board info>, "father": <int: Parent index in favboard, -1 for root entry>, "type": <string: Type of this entry, "board"/"dir"> } </source> === 列出收藏夹 === : '''GET''' /favboard/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | father || int || Parent directory of boards to list || Yes |- | start || int || ID of the first entry to list || Yes |- | end || int || ID of the last entry to list || Yes |- | count || int || Number of entries to list || Yes |} * Return value ** Success: <source lang="javascript"> [ FavBoardEntry, ... ] </source> === 列出某个项目的所有祖先项目 === : '''GET''' /favboard/dirnames {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | index || int || Index of the entry || No |} * Return value ** Success: <source lang="javascript"> [ FavBoardEntry, // the current entry FavBoardEntry, // its father FavBoardEntry, // its grandfather ... ] </source> == 会话 == === 验证会话 === : '''GET''' /session/verify {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} == 精华区 == DigestItem: <source lang="javascript"> { 'mtitle': <string: menu title when listing children of this item>, 'title': <string: title of this item>, 'attach': <int: attachment position or attachment flag, with attachment <-> != 0>, 'mtime': <int: modification time>, 'type': <string: item type. can be file/dir/link/other>, 'id': <int: item index, start from 1>, // these items only appear if type == link 'host': <string: link host>, 'post': <int: link port> } </source> === 列出目录 === : '''GET''' /digest/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the directory. Like x-1-2-3 || No |- | start || int || Number of the first item || Yes |- | end || int || Number of the last item || Yes |} Result: <source lang="javascript"> { 'parent': <DigestItem: information of the directory>, 'count': <int: number of items returned>, 'items': [ <DigestItem: information of one item>, ... ] } </source> === 获取帖子 === : '''GET''' /digest/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | board || string || Board name of the digest. If not present, start from the Digest menu. || Yes |- | route || string || Route to the post. Like x-1-2-3 || No |} Result: <source lang="javascript"> { 'item': <DigestItem: information of the post item>, <*PostContent: content of the post>, 'attachlink': <string: URL of the page showing attachments. add '&a=offset' for individual attachment> } </source> == 用户 == === 获取用户信息 === : '''GET''' /user/query {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |- | id || string || ID of user to query, omit to query yourself || Yes |} === 获取用户详细信息 === : '''GET''' /user/detail {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} === 获取默认签名档编号 === : '''GET''' /user/signature_id {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | session || string || Session Token || No |} * Return value: <source lang="javascript"> {"signature_id": <int: default signature id>} </source> === 注册新用户 === : '''POST''' /user/register {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional |- | username || string || User ID || No |- | password || string || Password || No |- | nick || string || Nick name || No |- | email || string || Email || No |- | realname || string || Real name || No |- | address || string || Address || No |- | birthyear || int || Birth year || No |- | birthmonth || int || Birth month || No |- | birthday || int || Birth day || No |- | gender || string || Gender (F/M) || No |- | selfintro || string || Self Introduction || Yes |- | phone || string || Contact information || No |- | career || string || Class information || No |} * Return value: <source lang="javascript"> {"result": "ok"} </source> == 存储 == 主要是用来上传文件,随后可以用于贴附件。 === 上传文件 === : '''POST''' /store/new {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || Session Token || No || |- | item || string || Storage item type || No || attachment |- | content || string || Base64-encoded content || No || |} * Return value: <source lang="javascript"> {"id": <string: ID of the item created>} </source> == 邮箱 == MailInfo: <source lang="javascript"> { "posttime": <time: post time>, "attachflag": <int: unknown>, "read": <boolean: read/unread>, "title": <string: Post title>, "attachment": <int: attachment count>, "owner": <string: mailer userid>, "id": <int: mail id>, "flags": [<string: one flag>, ...] } </source> * flags: marked, replied, forwarded MailContent: <source lang="javascript"> { "picattach": [ <AttachInfo: information of one attachment>, ... ], "otherattach": [ <AttachInfo: information of one attachment>, ... ], "content": <string: mail content> } </source> === 列出邮件 === : '''GET''' /mail/list {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | start || int || first mail index, start from 1 || yes |- | end || int || last mail index || yes |- | count || int || number of mails to list || yes |} * Return value: <source lang="javascript"> { "start": <int: first mail index>, "end": <int: last mail index>, "mails": [ <MailInfo: information of one mail>, ... ] } </source> === 阅读邮件 === : '''GET''' /mail/view {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || which folder to list || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |} * Return value: <source lang="javascript"> { <*MailContent: content of one mail>, <*MailInfo: information of one mail> } </source> === 引用邮件 === : '''GET''' /mail/quote {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | folder || string || the folder of the quoted mail || yes || '''inbox'''/sent |- | index || int || mail index, start from 1 || yes |- | mode || string || quote mode, same as post/quote || yes || '''S'''/R/N/A |} * Return value: <source lang="javascript"> { "title": <string: quoted title>, "content": <string: quoted content> } </source> 引用某个邮件箱里的某封邮件,可选引用模式。 === 发邮件 === : '''POST''' /mail/send {| class="wikitable" |- ! Parameter !! Type !! Description !! Optional !! Choices |- | session || string || session token || no || |- | to || string || receiver id || no || |- | title || string || mail title || no || |- | content || string || mail content || no || |- | signature_id || int || signature id || yes || '''0(none)'''/-1(random)/>0 |- | save_in_sent || int || save the mail in the sent box || yes || '''1'''/0 |} * Return value: <source lang="javascript"> {"result": "ok"} </source> 发邮件,可选是否存发件箱。 如果需要引用邮件,请先调用/mail/quote。 b4a5130b547ecfce058f3b68072a4baeed2596dd Hints 0 120 425 411 2015-01-16T20:29:01Z HenryHu 1 wikitext text/x-wiki * Undefined symbol "PL_thr_key" referenced from COPY relocation in /usr/local/bin/vim 重装perl,打开threads支持 * javac: target release 1.5 conflicts with default source release 1.7 在javac的参数里加上-source 1.5 对于编译Android碰见这个情况,修改build/core/combo/javac.mk,在正确位置加上-source 1.5 9365ce24c14f9b56c7fee98ad4e65742c27b092f 430 425 2015-02-04T19:35:09Z HenryHu 1 wikitext text/x-wiki * Undefined symbol "PL_thr_key" referenced from COPY relocation in /usr/local/bin/vim 重装perl,打开threads支持 * javac: target release 1.5 conflicts with default source release 1.7 在javac的参数里加上-source 1.5 对于编译Android碰见这个情况,修改build/core/combo/javac.mk,在正确位置加上-source 1.5 * cups: Add Printer: Forbidden 一般的说法是改cupsd.conf,让大家都能管理就好了。 其实只要把用户加入lpadmin组就可以了。这源自cups-files.conf里的一句话: <pre>SystemGroup lpadmin</pre> 所以@SYSTEM对应的就是lpadmin组。 78da5c0aebe2b0b1da237b5a6f67b256513984b6 Wine Video 0 122 426 2015-02-01T00:45:00Z HenryHu 1 以“Wine下的视频播放 == WVC1 == WVC1 (Windows Media Video 9 Advanced Profile) 出现在某些WMV文件里。 这货的解码器随WMP11附带。如果你只有WM...”为内容创建页面 wikitext text/x-wiki Wine下的视频播放 == WVC1 == WVC1 (Windows Media Video 9 Advanced Profile) 出现在某些WMV文件里。 这货的解码器随WMP11附带。如果你只有WMP9/10,那播放的时候会说没有codec。这时候你需要 http://support.microsoft.com/kb/942423/zh-cn 装里面的Hotfix,就可以有解码器。 a6f5ad63184e27b393154909b4ec66f1279cd836 24bit audio 0 123 434 2015-02-28T05:12:05Z HenryHu 1 以“== Available MPD outputs == * libao: mpd would not use 24bit, maybe unsupported * pulseaudio: 24bit unsupported in oss plugin * openal: 24bit unsupported * oss: some...”为内容创建页面 wikitext text/x-wiki == Available MPD outputs == * libao: mpd would not use 24bit, maybe unsupported * pulseaudio: 24bit unsupported in oss plugin * openal: 24bit unsupported * oss: some bug prevent it using 24bit correctly on freebsd 4c3e3abaac9b33b23df35bfb7e504a1da4ea317e Software of Choice 0 124 435 2015-03-29T00:59:22Z HenryHu 1 以“== PDF Viewer == Okular (from KDE project) == File Manager == Dolphin (from KDE project) == Console == rxvt-unicode == Window Manager == Compiz + Emerald == Brow...”为内容创建页面 wikitext text/x-wiki == PDF Viewer == Okular (from KDE project) == File Manager == Dolphin (from KDE project) == Console == rxvt-unicode == Window Manager == Compiz + Emerald == Browser == Firefox == Archiver == Ark (from KDE project) == Photo Viewer == GThumb (from GNOME project) == Calculator == gcalctool kcalc 92edf6f4694804c70759ecb27075bd407703db28 SubsConscious 0 3 436 75 2015-04-08T03:56:24Z HenryHu 1 /* 关键词 */ wikitext text/x-wiki SubsConscious 是哥大边上,Amsterdam Av. 上的一个店,主营subs和salad SubsConscious: great food. great service. www.subsconscious.com === 关键词 === 材料: * Turkey * Beef * Chicken Cutlet 炸鸡块 配料:Onion Cheese: Sauce: === 评价 === * graduate 过来之后吃的第一种,挺好吃的,郭总推荐,郭总基本上只吃这个…… * lecture 本来我觉得是各种里面最好的,但是有一次有一个很不好吃。不过那个好像是拿错了,因为里面有炸鱼…… 补充:那个的确拿错了,后来又吃了一次,的确很好吃 * ivy-league 好像不是很好吃…… * double-trouble 挺好吃的 * bar exam Jingyue推荐的,有beef,味道不错 * bronx-10461 刚开始吃感觉不错,不过吃到后来有奇怪的味道。貌似有汉堡里面那种蔬菜。 * twice-as-nice 挺不好吃的…… * valedictorian 不错,turkey系列之一,不过名字不好读 * iq 这就是上次lecture拿错的那个!不太好吃 * gpa 这个里面也有鱼,不过好像味道稍微好一些…… 等等,这个绿色的粘稠液体是啥…… 大概是蔬菜酱…… 幸好不是芥末…… 这个酱吃起来太恶心了…… 以后不要了…… * life-guard 终于凑满了10个,吃了个life guard 和graduate很像…… 不错 * triple-play 嗯,味道挺淡的。和lecture有点像,不过有好多青椒和生菜。一般。 * lions-den 非常好吃 * al's-advantage 比lions-den更好吃,基本上是最高水平 今儿又吃了一次,的确不错,没有任何缺陷 其实挺像汉堡的味道…… 80e79dcdd473f26833d1e2f8fd210aa4e5791613 History of RCS 0 125 437 2015-09-02T20:34:41Z HenryHu 1 以“== PhD students == * Jingyue Wu [GRADUATED] (Google) * Heming Cui [GRADUATED] (Hong Kong University) * Huayang Guo [QUIT] * Gang Hu * Yang Tang * Xinhao Yuan * Xin L...”为内容创建页面 wikitext text/x-wiki == PhD students == * Jingyue Wu [GRADUATED] (Google) * Heming Cui [GRADUATED] (Hong Kong University) * Huayang Guo [QUIT] * Gang Hu * Yang Tang * Xinhao Yuan * Xin Lu [QUIT] * David Williams King * Rui Gu * Lingmei Weng == MS students == * Wentian Cui (Amazon) * Xinan Xu (Amazon) * Yihong Lin (Google) * Lingyuan He * Zheang Li * Younghoon Jeon == Interns == * Tianyu == Post-docs == * Hao Li == Viewing scholars == 934f02df73145c0f7dd13d067f673b29701aa5a7 438 437 2015-09-02T20:35:16Z HenryHu 1 /* MS students */ wikitext text/x-wiki == PhD students == * Jingyue Wu [GRADUATED] (Google) * Heming Cui [GRADUATED] (Hong Kong University) * Huayang Guo [QUIT] * Gang Hu * Yang Tang * Xinhao Yuan * Xin Lu [QUIT] * David Williams King * Rui Gu * Lingmei Weng == MS students == * Wentian Cui (Amazon) * Xinan Xu (Amazon) * Yihong Lin (Google) * Lingyuan He * Zheang Li * Younghoon Jeon * Yu Qiao == Interns == * Tianyu == Post-docs == * Hao Li == Viewing scholars == 51bc96a72689059f1896d61386c11b1fd38decc5 441 438 2015-09-08T21:21:23Z HenryHu 1 /* PhD students */ wikitext text/x-wiki == PhD students == * Jingyue Wu [GRADUATED] (Google) * Heming Cui [GRADUATED] (Hong Kong University) * John Galleger [QUIT] * Huayang Guo [QUIT] * Gang Hu * Yang Tang * Xinhao Yuan * Xin Lu [QUIT] * David Williams King * Rui Gu * Lingmei Weng == MS students == * Wentian Cui (Amazon) * Xinan Xu (Amazon) * Yihong Lin (Google) * Lingyuan He * Zheang Li * Younghoon Jeon * Yu Qiao == Interns == * Tianyu == Post-docs == * Hao Li == Viewing scholars == eed2f78fd397c346deb76752df689ce90e68b301 Uhidd 0 126 439 2015-09-05T18:23:19Z HenryHu 1 以“# config file ### Not yet supported: # Power keys (sleep, etc.) # Not in consumer control group. # type=Application page=Generic_Desktop usage=System_Power_Down...”为内容创建页面 wikitext text/x-wiki # config file ### Not yet supported: # Power keys (sleep, etc.) # Not in consumer control group. # type=Application page=Generic_Desktop usage=System_Power_Down # type=Application page=Generic_Desktop usage=System_Sleep # type=Application page=Generic_Desktop usage=System_Wake_Up # default={ detach_kernel_driver="NO" kbd_attach="NO" mouse_attach="NO" # Unused keycodes Currently unused keycodes include: 0x54, 0x5A, # 0x5F, 0x60, 0x62, 0x63, 0x6F, 0x71, 0x72, 0x74. # # Rarely used keycodes 0x73, 0x70, 0x7D, 0x79, 0x7B, 0x5C, 0xF2, 0xF1, # 0x78, 0x77, 0x76. These keycodes are most likely # not used for English keyboard. # # F13 - F24 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, # 0x6C, 0x6D, 0x6E, 0x76. These keycodes are for # extra function keys found on some keyboards and can # be reassigned if your keyboard doesn't have them. # #keycode 207 = XF86AudioMute #keycode 189 = XF86AudioLowerVolume #keycode 190 = XF86AudioRaiseVolume #keycode 92 = XF86AudioPlay #keycode 170 = XF86AudioStop #keycode 130 = XF86AudioPrev #keycode 132 = XF86AudioNext cc_keymap={ # 0x63 -> 190 DELTA = 91 Volume_Increment="0x63" Volume_Decrement="0x62" # 0x7c -> 132 DELTA = 8 Scan_Next_Track="0x7c" Scan_Previous_Track="0x7a" # 0x5a -> 170 or 164 Stop="0x5a" # 0x54 -> 92 DELTA = 8 Play/Pause="0x54" # 0x6f -> 207 DELTA = 96 Mute="0x6f" } # sc_attach="YES" # sc_keymap={ # Sleep="0x64" # } } 0x046d:0xc31={ detach_kernel_driver="NO" } # Logitech receiver ## Keyboard 0x046d:0xc52b:0={ detach_kernel_driver="NO" } ## Mouse, Media keys 0x046d:0xc52b:1={ detach_kernel_driver="YES" mouse_attach="YES" cc_attach="YES" vhid_attach="YES" } ## HID device 0x046d:0xc52b:2={ detach_kernel_driver="NO" } # Code Keyboard ## Keyboard 0x04d9:0x0169:0={ detach_kernel_driver="NO" } ## HID device for media keys 0x04d9:0x0169:1={ detach_kernel_driver="YES" cc_attach="YES" } # DasKeyboard 4C ## Keyboard 0x24f0:0x0142:0={ detach_kernel_driver="NO" } ## HID device for media keys 0x24f0:0x0142:1={ detach_kernel_driver="YES" cc_attach="YES" vhid_attach="YES" } e47dc10d75b17951733b9460b1cc9d2b114335af 440 439 2015-09-05T18:28:23Z HenryHu 1 wikitext text/x-wiki == uhidd == 用户态处理HID设备事件的程序 == uvhid == uhidd建立的伪HID设备,可用于usbhidaction和usbhidctl。 因为不支持USB_GET_REPORT,usbhidctl需要-z参数。 在github.com/HenryHu/uhidd中有实验性修正。 == uhidd.conf == <pre> # config file ### Not yet supported: # Power keys (sleep, etc.) # Not in consumer control group. # type=Application page=Generic_Desktop usage=System_Power_Down # type=Application page=Generic_Desktop usage=System_Sleep # type=Application page=Generic_Desktop usage=System_Wake_Up # default={ detach_kernel_driver="NO" kbd_attach="NO" mouse_attach="NO" # Unused keycodes Currently unused keycodes include: 0x54, 0x5A, # 0x5F, 0x60, 0x62, 0x63, 0x6F, 0x71, 0x72, 0x74. # # Rarely used keycodes 0x73, 0x70, 0x7D, 0x79, 0x7B, 0x5C, 0xF2, 0xF1, # 0x78, 0x77, 0x76. These keycodes are most likely # not used for English keyboard. # # F13 - F24 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, # 0x6C, 0x6D, 0x6E, 0x76. These keycodes are for # extra function keys found on some keyboards and can # be reassigned if your keyboard doesn't have them. # # Corresponding entries in .Xmodmap: # #keycode 207 = XF86AudioMute #keycode 189 = XF86AudioLowerVolume #keycode 190 = XF86AudioRaiseVolume #keycode 92 = XF86AudioPlay #keycode 170 = XF86AudioStop #keycode 130 = XF86AudioPrev #keycode 132 = XF86AudioNext cc_keymap={ # 0x63 -> 190 DELTA = 91 Volume_Increment="0x63" Volume_Decrement="0x62" # 0x7c -> 132 DELTA = 8 Scan_Next_Track="0x7c" Scan_Previous_Track="0x7a" # 0x5a -> 170 or 164 Stop="0x5a" # 0x54 -> 92 DELTA = 8 Play/Pause="0x54" # 0x6f -> 207 DELTA = 96 Mute="0x6f" } # sc_attach="YES" # sc_keymap={ # Sleep="0x64" # } } 0x046d:0xc31={ detach_kernel_driver="NO" } # Logitech receiver ## Keyboard 0x046d:0xc52b:0={ detach_kernel_driver="NO" } ## Mouse, Media keys 0x046d:0xc52b:1={ detach_kernel_driver="YES" mouse_attach="YES" cc_attach="YES" vhid_attach="YES" } ## HID device 0x046d:0xc52b:2={ detach_kernel_driver="NO" } # Code Keyboard ## Keyboard 0x04d9:0x0169:0={ detach_kernel_driver="NO" } ## HID device for media keys 0x04d9:0x0169:1={ detach_kernel_driver="YES" cc_attach="YES" } # DasKeyboard 4C ## Keyboard 0x24f0:0x0142:0={ detach_kernel_driver="NO" } ## HID device for media keys 0x24f0:0x0142:1={ detach_kernel_driver="YES" cc_attach="YES" vhid_attach="YES" } </pre> 0ccc488e1bd5e05c689d8d34c01013c2a7760006 Wine Font 0 101 442 345 2015-10-24T22:58:37Z Nuk 25 wikitext text/x-wiki 关于如何在Wine里面配置字体,特别是中文字体。 test == 调试信息 == 要看调试信息,跑 env WINEDEBUG=+font wine <program> 具体WINEDEBUG可以参见<ref>[http://wiki.winehq.org/DebugChannels Debug Logging]</ref>。 == 相关注册表位置 == 基本上在<ref name="reg">[http://wiki.winehq.org/UsefulRegistryKeys Useful Registry Keys]</ref>里面说了。 === HKEY_CURRENT_USER\Software\Wine\Fonts === 这里底下有几个: * Cache 底下有各个字体的信息的缓存,删掉这个分支也会自动重建,最多能暂时解决问题,没啥用。 里面可以查到各个字体名字。如果有English Name属性那也能作为名字用。 * External Fonts 字体列表,应该也是自动产生的 * Replacements 第一个可以用于替换字体的位置,在里面弄个字符串值,<要替换的>=<替换为>,就可以了。 据说如果能找到要替换的字体这个就不起作用,所以这也就是个 fallback 而已。 === HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion === 这里有另外几个相关的键值<ref name="reg"/>。 * FontLink/SystemLink 这里可以把字体和字体文件对应起来。 目前尝试貌似只能找到不带路径的字体,在Windows\Fonts目录里。也是字符串值,格式是<字体名>=<字体文件>。 例如,如果要让MS Sans Serif用微米黑,写 name: “MS Sans Serif” value: “wqy-microhei.ttc” 并把wqy-microhei.ttc放到windows的fonts目录就可以了。 * Fonts 系统级的字体列表,和上面的External Fonts貌似类似,可能也是自动生成的。 * FontSubstitutes 另一个可以替换字体的地方,格式和上面的Replacements一样。不过这里貌似不管实际字体存不存在都会替换。 另外,如果这里作为被替换的字体出现的话,上面SystemLink就会失效(废话……)。 == 配置方法 == 看了上面的可以知道,基本上只要搞SystemLink和FontSubstitutes就可以了。 SystemLink关联到字体文件,FontSubstitutes把别的字体替换成这个。 其实只要把要搞的字体都在SystemLink里关联了就完了。FontSubstitutes里有一堆系统默认搞了的。 貌似要搞的字体有: * Arial * Arial Black * Microsoft Sans Serif // 可能不需要 * MS Sans Serif // 需要 * SimSun * System // 谁知道呢…… * Tahoma * Tahoma Bold == 参见 == <references/> 4e222169b85fc4097eee050498895615256eb6b5 443 442 2015-10-24T23:02:48Z Nuk 25 wikitext text/x-wiki 关于如何在Wine里面配置字体,特别是中文字体。 == 调试信息 == 要看调试信息,跑 env WINEDEBUG=+font wine <program> 具体WINEDEBUG可以参见<ref>[http://wiki.winehq.org/DebugChannels Debug Logging]</ref>。 == 相关注册表位置 == 基本上在<ref name="reg">[http://wiki.winehq.org/UsefulRegistryKeys Useful Registry Keys]</ref>里面说了。 === HKEY_CURRENT_USER\Software\Wine\Fonts === 这里底下有几个: * Cache 底下有各个字体的信息的缓存,删掉这个分支也会自动重建,最多能暂时解决问题,没啥用。 里面可以查到各个字体名字。如果有English Name属性那也能作为名字用。 * External Fonts 字体列表,应该也是自动产生的 * Replacements 第一个可以用于替换字体的位置,在里面弄个字符串值,<要替换的>=<替换为>,就可以了。 据说如果能找到要替换的字体这个就不起作用,所以这也就是个 fallback 而已。 === HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion === 这里有另外几个相关的键值<ref name="reg"/>。 * FontLink/SystemLink 这里可以把字体和字体文件对应起来。 目前尝试貌似只能找到不带路径的字体,在Windows\Fonts目录里。也是字符串值,格式是<字体名>=<字体文件>。 例如,如果要让MS Sans Serif用微米黑,写 name: “MS Sans Serif” value: “wqy-microhei.ttc” 并把wqy-microhei.ttc放到windows的fonts目录就可以了。 * Fonts 系统级的字体列表,和上面的External Fonts貌似类似,可能也是自动生成的。 * FontSubstitutes 另一个可以替换字体的地方,格式和上面的Replacements一样。不过这里貌似不管实际字体存不存在都会替换。 另外,如果这里作为被替换的字体出现的话,上面SystemLink就会失效(废话……)。 == Wine的默认字体 == 这里收集一些wine(版本1.6.2)使用的默认字体 {|- ! 菜单栏字体 ! 文本框字体 ! Tooltip字体 |- | ??? | Tahoma | ??? |} == 配置方法 == 看了上面的可以知道,基本上只要搞SystemLink和FontSubstitutes就可以了。 SystemLink关联到字体文件,FontSubstitutes把别的字体替换成这个。 其实只要把要搞的字体都在SystemLink里关联了就完了。FontSubstitutes里有一堆系统默认搞了的。 貌似要搞的字体有: * Arial * Arial Black * Microsoft Sans Serif // 可能不需要 * MS Sans Serif // 需要 * SimSun * System // 谁知道呢…… * Tahoma * Tahoma Bold == 参见 == <references/> 9aed06d2659125b413895f5dd3ffc03d0be1c349 444 443 2015-10-24T23:05:04Z Nuk 25 wikitext text/x-wiki 关于如何在Wine里面配置字体,特别是中文字体。 == 调试信息 == 要看调试信息,跑 env WINEDEBUG=+font wine <program> 具体WINEDEBUG可以参见<ref>[http://wiki.winehq.org/DebugChannels Debug Logging]</ref>。 == 相关注册表位置 == 基本上在<ref name="reg">[http://wiki.winehq.org/UsefulRegistryKeys Useful Registry Keys]</ref>里面说了。 === HKEY_CURRENT_USER\Software\Wine\Fonts === 这里底下有几个: * Cache 底下有各个字体的信息的缓存,删掉这个分支也会自动重建,最多能暂时解决问题,没啥用。 里面可以查到各个字体名字。如果有English Name属性那也能作为名字用。 * External Fonts 字体列表,应该也是自动产生的 * Replacements 第一个可以用于替换字体的位置,在里面弄个字符串值,<要替换的>=<替换为>,就可以了。 据说如果能找到要替换的字体这个就不起作用,所以这也就是个 fallback 而已。 === HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion === 这里有另外几个相关的键值<ref name="reg"/>。 * FontLink/SystemLink 这里可以把字体和字体文件对应起来。 目前尝试貌似只能找到不带路径的字体,在Windows\Fonts目录里。也是字符串值,格式是<字体名>=<字体文件>。 例如,如果要让MS Sans Serif用微米黑,写 name: “MS Sans Serif” value: “wqy-microhei.ttc” 并把wqy-microhei.ttc放到windows的fonts目录就可以了。 * Fonts 系统级的字体列表,和上面的External Fonts貌似类似,可能也是自动生成的。 * FontSubstitutes 另一个可以替换字体的地方,格式和上面的Replacements一样。不过这里貌似不管实际字体存不存在都会替换。 另外,如果这里作为被替换的字体出现的话,上面SystemLink就会失效(废话……)。 == Wine的默认字体 == 这里写明一些wine(版本1.6.2)在系统界面使用的默认字体 菜单栏字体:MS 文本框及对话框字体:Tahoma == 配置方法 == 看了上面的可以知道,基本上只要搞SystemLink和FontSubstitutes就可以了。 SystemLink关联到字体文件,FontSubstitutes把别的字体替换成这个。 其实只要把要搞的字体都在SystemLink里关联了就完了。FontSubstitutes里有一堆系统默认搞了的。 貌似要搞的字体有: * Arial * Arial Black * Microsoft Sans Serif // 可能不需要 * MS Sans Serif // 需要 * SimSun * System // 谁知道呢…… * Tahoma * Tahoma Bold == 参见 == <references/> 0b860b16b9d03dad623bfecb5969f3839c52e386 445 444 2015-10-24T23:24:24Z Nuk 25 wikitext text/x-wiki 关于如何在Wine里面配置字体,特别是中文字体。 == 调试信息 == 要看调试信息,跑 env WINEDEBUG=+font wine <program> 具体WINEDEBUG可以参见<ref>[http://wiki.winehq.org/DebugChannels Debug Logging]</ref>。 == 相关注册表位置 == 基本上在<ref name="reg">[http://wiki.winehq.org/UsefulRegistryKeys Useful Registry Keys]</ref>里面说了。 === HKEY_CURRENT_USER\Software\Wine\Fonts === 这里底下有几个: * Cache 底下有各个字体的信息的缓存,删掉这个分支也会自动重建,最多能暂时解决问题,没啥用。 里面可以查到各个字体名字。如果有English Name属性那也能作为名字用。 * External Fonts 字体列表,应该也是自动产生的 * Replacements 第一个可以用于替换字体的位置,在里面弄个字符串值,<要替换的>=<替换为>,就可以了。 据说如果能找到要替换的字体这个就不起作用,所以这也就是个 fallback 而已。 === HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion === 这里有另外几个相关的键值<ref name="reg"/>。 * FontLink/SystemLink 这里可以把字体和字体文件对应起来。 目前尝试貌似只能找到不带路径的字体,在Windows\Fonts目录里。也是字符串值,格式是<字体名>=<字体文件>。 例如,如果要让MS Sans Serif用微米黑,写 name: “MS Sans Serif” value: “wqy-microhei.ttc” 并把wqy-microhei.ttc放到windows的fonts目录就可以了。 * Fonts 系统级的字体列表,和上面的External Fonts貌似类似,可能也是自动生成的。 * FontSubstitutes 另一个可以替换字体的地方,格式和上面的Replacements一样。不过这里貌似不管实际字体存不存在都会替换。 另外,如果这里作为被替换的字体出现的话,上面SystemLink就会失效(废话……)。 == Wine的默认字体 == 这里写明一些wine(版本1.6.2)在系统界面使用的默认字体 * 菜单栏字体:MS Shell Dlg / MS Shell Dlg 2 (可以在winecfg中设置) * 文本框字体:Tahoma * 对话框字体:MS Shell Dlg / MS Shell Dlg 2 == 配置方法 == 看了上面的可以知道,基本上只要搞SystemLink和FontSubstitutes就可以了。 SystemLink关联到字体文件,FontSubstitutes把别的字体替换成这个。 其实只要把要搞的字体都在SystemLink里关联了就完了。FontSubstitutes里有一堆系统默认搞了的。 貌似要搞的字体有: * Arial * Arial Black * Microsoft Sans Serif // 可能不需要 * MS Sans Serif // 需要 * SimSun * System // 谁知道呢…… * Tahoma * Tahoma Bold == 参见 == <references/> 0cd1e6fc09f95abde788a69e87b8e490be65cdc7 460 445 2015-11-05T04:48:33Z Nuk 25 /* Wine的默认字体 */ wikitext text/x-wiki 关于如何在Wine里面配置字体,特别是中文字体。 == 调试信息 == 要看调试信息,跑 env WINEDEBUG=+font wine <program> 具体WINEDEBUG可以参见<ref>[http://wiki.winehq.org/DebugChannels Debug Logging]</ref>。 == 相关注册表位置 == 基本上在<ref name="reg">[http://wiki.winehq.org/UsefulRegistryKeys Useful Registry Keys]</ref>里面说了。 === HKEY_CURRENT_USER\Software\Wine\Fonts === 这里底下有几个: * Cache 底下有各个字体的信息的缓存,删掉这个分支也会自动重建,最多能暂时解决问题,没啥用。 里面可以查到各个字体名字。如果有English Name属性那也能作为名字用。 * External Fonts 字体列表,应该也是自动产生的 * Replacements 第一个可以用于替换字体的位置,在里面弄个字符串值,<要替换的>=<替换为>,就可以了。 据说如果能找到要替换的字体这个就不起作用,所以这也就是个 fallback 而已。 === HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion === 这里有另外几个相关的键值<ref name="reg"/>。 * FontLink/SystemLink 这里可以把字体和字体文件对应起来。 目前尝试貌似只能找到不带路径的字体,在Windows\Fonts目录里。也是字符串值,格式是<字体名>=<字体文件>。 例如,如果要让MS Sans Serif用微米黑,写 name: “MS Sans Serif” value: “wqy-microhei.ttc” 并把wqy-microhei.ttc放到windows的fonts目录就可以了。 * Fonts 系统级的字体列表,和上面的External Fonts貌似类似,可能也是自动生成的。 * FontSubstitutes 另一个可以替换字体的地方,格式和上面的Replacements一样。不过这里貌似不管实际字体存不存在都会替换。 另外,如果这里作为被替换的字体出现的话,上面SystemLink就会失效(废话……)。 == Wine的默认字体 == wine(版本1.6.2)在系统界面,会根据不同LOCALE设置不同的默认字体。 具体表现为修改HKLM下面FontSubstitute主键下面的相关键值。 en_US: Tahoma ja_JP: MS Gothic zh_CN: 宋体 == 配置方法 == 看了上面的可以知道,基本上只要搞SystemLink和FontSubstitutes就可以了。 SystemLink关联到字体文件,FontSubstitutes把别的字体替换成这个。 其实只要把要搞的字体都在SystemLink里关联了就完了。FontSubstitutes里有一堆系统默认搞了的。 貌似要搞的字体有: * Arial * Arial Black * Microsoft Sans Serif // 可能不需要 * MS Sans Serif // 需要 * SimSun * System // 谁知道呢…… * Tahoma * Tahoma Bold == 参见 == <references/> 5d7805b6860d0f0af97ea097c5e05dc8214ed6ea 461 460 2015-11-05T04:50:11Z Nuk 25 /* Wine的默认字体 */ wikitext text/x-wiki 关于如何在Wine里面配置字体,特别是中文字体。 == 调试信息 == 要看调试信息,跑 env WINEDEBUG=+font wine <program> 具体WINEDEBUG可以参见<ref>[http://wiki.winehq.org/DebugChannels Debug Logging]</ref>。 == 相关注册表位置 == 基本上在<ref name="reg">[http://wiki.winehq.org/UsefulRegistryKeys Useful Registry Keys]</ref>里面说了。 === HKEY_CURRENT_USER\Software\Wine\Fonts === 这里底下有几个: * Cache 底下有各个字体的信息的缓存,删掉这个分支也会自动重建,最多能暂时解决问题,没啥用。 里面可以查到各个字体名字。如果有English Name属性那也能作为名字用。 * External Fonts 字体列表,应该也是自动产生的 * Replacements 第一个可以用于替换字体的位置,在里面弄个字符串值,<要替换的>=<替换为>,就可以了。 据说如果能找到要替换的字体这个就不起作用,所以这也就是个 fallback 而已。 === HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion === 这里有另外几个相关的键值<ref name="reg"/>。 * FontLink/SystemLink 这里可以把字体和字体文件对应起来。 目前尝试貌似只能找到不带路径的字体,在Windows\Fonts目录里。也是字符串值,格式是<字体名>=<字体文件>。 例如,如果要让MS Sans Serif用微米黑,写 name: “MS Sans Serif” value: “wqy-microhei.ttc” 并把wqy-microhei.ttc放到windows的fonts目录就可以了。 * Fonts 系统级的字体列表,和上面的External Fonts貌似类似,可能也是自动生成的。 * FontSubstitutes 另一个可以替换字体的地方,格式和上面的Replacements一样。不过这里貌似不管实际字体存不存在都会替换。 另外,如果这里作为被替换的字体出现的话,上面SystemLink就会失效(废话……)。 == Wine的默认字体 == wine(版本1.6.2)在系统界面,会根据不同LOCALE设置不同的默认字体。 具体表现为修改HKLM下面FontSubstitute主键下面的相关键值。 - en_US: Tahoma - ja_JP: MS Gothic - zh_CN: 宋体 == 配置方法 == 看了上面的可以知道,基本上只要搞SystemLink和FontSubstitutes就可以了。 SystemLink关联到字体文件,FontSubstitutes把别的字体替换成这个。 其实只要把要搞的字体都在SystemLink里关联了就完了。FontSubstitutes里有一堆系统默认搞了的。 貌似要搞的字体有: * Arial * Arial Black * Microsoft Sans Serif // 可能不需要 * MS Sans Serif // 需要 * SimSun * System // 谁知道呢…… * Tahoma * Tahoma Bold == 参见 == <references/> fc173c1d104e7e8e8ca4808858eba96494f36653 462 461 2015-11-05T04:50:25Z Nuk 25 /* Wine的默认字体 */ wikitext text/x-wiki 关于如何在Wine里面配置字体,特别是中文字体。 == 调试信息 == 要看调试信息,跑 env WINEDEBUG=+font wine <program> 具体WINEDEBUG可以参见<ref>[http://wiki.winehq.org/DebugChannels Debug Logging]</ref>。 == 相关注册表位置 == 基本上在<ref name="reg">[http://wiki.winehq.org/UsefulRegistryKeys Useful Registry Keys]</ref>里面说了。 === HKEY_CURRENT_USER\Software\Wine\Fonts === 这里底下有几个: * Cache 底下有各个字体的信息的缓存,删掉这个分支也会自动重建,最多能暂时解决问题,没啥用。 里面可以查到各个字体名字。如果有English Name属性那也能作为名字用。 * External Fonts 字体列表,应该也是自动产生的 * Replacements 第一个可以用于替换字体的位置,在里面弄个字符串值,<要替换的>=<替换为>,就可以了。 据说如果能找到要替换的字体这个就不起作用,所以这也就是个 fallback 而已。 === HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion === 这里有另外几个相关的键值<ref name="reg"/>。 * FontLink/SystemLink 这里可以把字体和字体文件对应起来。 目前尝试貌似只能找到不带路径的字体,在Windows\Fonts目录里。也是字符串值,格式是<字体名>=<字体文件>。 例如,如果要让MS Sans Serif用微米黑,写 name: “MS Sans Serif” value: “wqy-microhei.ttc” 并把wqy-microhei.ttc放到windows的fonts目录就可以了。 * Fonts 系统级的字体列表,和上面的External Fonts貌似类似,可能也是自动生成的。 * FontSubstitutes 另一个可以替换字体的地方,格式和上面的Replacements一样。不过这里貌似不管实际字体存不存在都会替换。 另外,如果这里作为被替换的字体出现的话,上面SystemLink就会失效(废话……)。 == Wine的默认字体 == wine(版本1.6.2)在系统界面,会根据不同LOCALE设置不同的默认字体。 具体表现为修改HKLM下面FontSubstitute主键下面的相关键值。 * en_US: Tahoma * ja_JP: MS Gothic * zh_CN: 宋体 == 配置方法 == 看了上面的可以知道,基本上只要搞SystemLink和FontSubstitutes就可以了。 SystemLink关联到字体文件,FontSubstitutes把别的字体替换成这个。 其实只要把要搞的字体都在SystemLink里关联了就完了。FontSubstitutes里有一堆系统默认搞了的。 貌似要搞的字体有: * Arial * Arial Black * Microsoft Sans Serif // 可能不需要 * MS Sans Serif // 需要 * SimSun * System // 谁知道呢…… * Tahoma * Tahoma Bold == 参见 == <references/> f3bcde6bcaf3acb10532ebdb5afec81fabe6ef96 Wine Registry 0 127 446 2015-10-25T20:22:40Z Nuk 25 以“= 这里记录一些有用的Wine 注册表信息 = == 已经安装的程序列表(出现在wine uninstaller中) == * [Software\\Microsoft\\Windows\\CurrentVe...”为内容创建页面 wikitext text/x-wiki = 这里记录一些有用的Wine 注册表信息 = == 已经安装的程序列表(出现在wine uninstaller中) == * [Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\] * [Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\] 1459dec95b43908ba73f480d45cf5979b1a22edc 447 446 2015-10-25T20:22:52Z Nuk 25 wikitext text/x-wiki = 这里记录一些有用的Wine 注册表信息 = == 已经安装的程序列表(出现在wine uninstaller中) == * [Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\] * [Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\] 27c70dfc2fbed778bc7ca4ca70a8a729b1a27638 448 447 2015-10-25T20:24:40Z Nuk 25 /* 已经安装的程序列表(出现在wine uninstaller中) */ wikitext text/x-wiki = 这里记录一些有用的Wine 注册表信息 = == 已经安装的程序列表(出现在wine uninstaller中) == * [Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\] * [Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\] 这些信息会被记录在~/.wine目录下的system.reg以及user.reg中。 bbbd0fdd152cc28085e17202d7a2f0ecb305970e 449 448 2015-10-25T20:27:03Z Nuk 25 /* 已经安装的程序列表(出现在wine uninstaller中) */ wikitext text/x-wiki = 这里记录一些有用的Wine 注册表信息 = == 已经安装的程序列表(显示在wine uninstaller中) == * [Software\Microsoft\Windows\CurrentVersion\App Paths\] * [Software\Microsoft\Windows\CurrentVersion\Uninstall\] 这些信息会被记录在~/.wine目录下的system.reg以及user.reg中。 ee357088a037e50b53c6947b0e86a62b19db6fdb Wine Game 0 128 450 2015-10-26T14:25:49Z Nuk 25 以“本页列出一系列Wine 成功的游戏列表 == Kirikiri引擎 == * 魔法使之夜 == BGI引擎 == * 樱之诗 * 素晴日 == ELF会社 == * 媚肉之香...”为内容创建页面 wikitext text/x-wiki 本页列出一系列Wine 成功的游戏列表 == Kirikiri引擎 == * 魔法使之夜 == BGI引擎 == * 樱之诗 * 素晴日 == ELF会社 == * 媚肉之香 * 同级生2 97Win版 == IG会社 == * 和之匣 2923beb6e42f98318096b604d1d88237720efee6 451 450 2015-10-26T14:28:08Z Nuk 25 wikitext text/x-wiki 本页列出一系列测试过Wine的游戏列表。 一般来说中文游戏用LANG=zh_CN wine XXX.exe,日文游戏用LANG=ja_JP wine XXX.exe即可。 == 型月 == * 魔法使之夜 == 枕头社 == * 樱之诗 * 素晴日 * 灯穗奇谭(需要在注册表中把渲染模式从opengl修改为GDI,原因不明) == ELF会社 == * 媚肉之香 * 同级生2 97Win版 == IG会社 == * 和之匣 8fc3fd239b6940418da5a38ce105c44c39ed6c04 455 451 2015-10-26T21:20:11Z Nuk 25 /* ELF会社 */ wikitext text/x-wiki 本页列出一系列测试过Wine的游戏列表。 一般来说中文游戏用LANG=zh_CN wine XXX.exe,日文游戏用LANG=ja_JP wine XXX.exe即可。 == 型月 == * 魔法使之夜 == 枕头社 == * 樱之诗 * 素晴日 * 灯穗奇谭(需要在注册表中把渲染模式从opengl修改为GDI,原因不明) == ELF会社 == * 媚肉之香 * 同级生2 97Win版 文本字体:新宋体 trace:font:dump_gdi_font_list font=0x1c25d0 ref=0 L"\65b0\5b8b\4f53" -16 == IG会社 == * 和之匣 c360fb109929f8b29441009d3045e5dd146274d1 456 455 2015-10-26T21:45:54Z Nuk 25 /* ELF会社 */ wikitext text/x-wiki 本页列出一系列测试过Wine的游戏列表。 一般来说中文游戏用LANG=zh_CN wine XXX.exe,日文游戏用LANG=ja_JP wine XXX.exe即可。 == 型月 == * 魔法使之夜 == 枕头社 == * 樱之诗 * 素晴日 * 灯穗奇谭(需要在注册表中把渲染模式从opengl修改为GDI,原因不明) == ELF会社 == * 媚肉之香 文本字体:黑体 * 同级生2 97Win版 文本字体:新宋体 trace:font:dump_gdi_font_list font=0x1c25d0 ref=0 L"\65b0\5b8b\4f53" -16 == IG会社 == * 和之匣 62dbe001295222a850be15212fc314ee238a82e0 457 456 2015-10-26T22:01:53Z Nuk 25 /* 枕头社 */ wikitext text/x-wiki 本页列出一系列测试过Wine的游戏列表。 一般来说中文游戏用LANG=zh_CN wine XXX.exe,日文游戏用LANG=ja_JP wine XXX.exe即可。 == 型月 == * 魔法使之夜 == 枕头社 == * 樱之诗 字体:MS ゴシック * 素晴日 * 灯穗奇谭(需要在注册表中把渲染模式从opengl修改为GDI,原因不明) 字体: SimHei、MS Pゴシック == ELF会社 == * 媚肉之香 文本字体:黑体 * 同级生2 97Win版 文本字体:新宋体 trace:font:dump_gdi_font_list font=0x1c25d0 ref=0 L"\65b0\5b8b\4f53" -16 == IG会社 == * 和之匣 9bfc314377740bd5d8168bd321473348a371fdd7 458 457 2015-10-26T22:59:55Z Nuk 25 /* ELF会社 */ wikitext text/x-wiki 本页列出一系列测试过Wine的游戏列表。 一般来说中文游戏用LANG=zh_CN wine XXX.exe,日文游戏用LANG=ja_JP wine XXX.exe即可。 == 型月 == * 魔法使之夜 == 枕头社 == * 樱之诗 字体:MS ゴシック * 素晴日 * 灯穗奇谭(需要在注册表中把渲染模式从opengl修改为GDI,原因不明) 字体: SimHei、MS Pゴシック == ELF会社 == * 媚肉之香 文本字体:黑体 读档时存在Read Illegal Memory的问题 * 同级生2 97Win版 文本字体:新宋体 trace:font:dump_gdi_font_list font=0x1c25d0 ref=0 L"\65b0\5b8b\4f53" -16 == IG会社 == * 和之匣 dff71cd986d57d14e74143830b041afb54042552 459 458 2015-10-26T23:11:12Z Nuk 25 /* IG会社 */ wikitext text/x-wiki 本页列出一系列测试过Wine的游戏列表。 一般来说中文游戏用LANG=zh_CN wine XXX.exe,日文游戏用LANG=ja_JP wine XXX.exe即可。 == 型月 == * 魔法使之夜 == 枕头社 == * 樱之诗 字体:MS ゴシック * 素晴日 * 灯穗奇谭(需要在注册表中把渲染模式从opengl修改为GDI,原因不明) 字体: SimHei、MS Pゴシック == ELF会社 == * 媚肉之香 文本字体:黑体 读档时存在Read Illegal Memory的问题 * 同级生2 97Win版 文本字体:新宋体 trace:font:dump_gdi_font_list font=0x1c25d0 ref=0 L"\65b0\5b8b\4f53" -16 == IG会社 == * 和之匣 * 虚の少女 试图播放开场影片时访问0x0报错退出 efafadd67591569980dd2e9ec3747e6d8b5a31ef 用户:Nuk 2 129 452 2015-10-26T14:29:04Z Nuk 25 以“User name: Nuk Contact: i@xuzhao.net”为内容创建页面 wikitext text/x-wiki User name: Nuk Contact: i@xuzhao.net 62f9844e4793d55b8ee5a80050bf4a24367b6e57 463 452 2015-11-05T04:54:28Z Nuk 25 wikitext text/x-wiki * User name: Nuk * Contact: i@xuzhao.net 2c84cadc590a90250dbebffab827d9b8ea27f7bd SuSE Font 0 130 453 2015-10-26T17:47:03Z Nuk 25 以“本页描述了openSUSE 13.2 下面字体显示不正常应该如何修改。 = font-family的修改 = 打开$HOME/.config/fontconfig/fonts.conf文件,修改如...”为内容创建页面 wikitext text/x-wiki 本页描述了openSUSE 13.2 下面字体显示不正常应该如何修改。 = font-family的修改 = 打开$HOME/.config/fontconfig/fonts.conf文件,修改如下: <?xml version="1.0"?> <!DOCTYPE fontconfig SYSTEM "fonts.dtd"> <fontconfig> <alias> <test name="user_preference_list"><bool>false</bool></test> <family>sans-serif</family> <prefer> <family>Arimo</family> <family>Noto Sans S Chinese</family> <family>Noto Sans Japanese</family> </prefer> </alias> <alias> <test name="user_preference_list"><bool>false</bool></test> <family>serif</family> <prefer> <family>Tinos</family> <family>Noto Sans S Chinese</family> <family>Noto Sans Japanese</family> </prefer> </alias> <alias> <test name="user_preference_list"><bool>false</bool></test> <family>monospace</family> <prefer> <family>Cousine</family> <family>Noto Sans S Chinese</family> <family>Noto Sans Japanese</family> </prefer> </alias> </fontconfig> = Verdana,Tahoma等字体关闭反锯齿 = 修改/etc/font.d/conf.d/10-group-tt-hinted-fonts.conf,注释掉Verdana,Tahoma和Microsoft YaHei相关的内容即可。 32b828be715b7e3672bcf700877024c9b32094ce 454 453 2015-10-26T17:47:29Z Nuk 25 /* font-family的修改 */ wikitext text/x-wiki 本页描述了openSUSE 13.2 下面字体显示不正常应该如何修改。 = font-family的修改 = 打开$HOME/.config/fontconfig/fonts.conf文件,修改如下: <?xml version="1.0"?> <!DOCTYPE fontconfig SYSTEM "fonts.dtd"> <fontconfig><alias> <test name="user_preference_list"><bool>false</bool></test> <family>sans-serif</family> <prefer> <family>Arimo</family> <family>Noto Sans S Chinese</family> <family>Noto Sans Japanese</family> </prefer> </alias> <alias> <test name="user_preference_list"><bool>false</bool></test> <family>serif</family> <prefer> <family>Tinos</family> <family>Noto Sans S Chinese</family> <family>Noto Sans Japanese</family> </prefer> </alias> <alias> <test name="user_preference_list"><bool>false</bool></test> <family>monospace</family> <prefer> <family>Cousine</family> <family>Noto Sans S Chinese</family> <family>Noto Sans Japanese</family> </prefer> </alias></fontconfig> = Verdana,Tahoma等字体关闭反锯齿 = 修改/etc/font.d/conf.d/10-group-tt-hinted-fonts.conf,注释掉Verdana,Tahoma和Microsoft YaHei相关的内容即可。 d4ea31b3f474cfb5fa24c52e808a71c8a7842128 Columbia Goodies 0 131 464 2015-11-24T21:16:46Z HenryHu 1 以“== Safari Books Online == * http://proquest.safaribooksonline.com/ Free E-Books == Apple == Student discount == Microsoft == === Office 365 === * http://www.offic...”为内容创建页面 wikitext text/x-wiki == Safari Books Online == * http://proquest.safaribooksonline.com/ Free E-Books == Apple == Student discount == Microsoft == === Office 365 === * http://www.office.com Free Subscription with .edu email === Visual Studio, Windows === * MSDNAA Find it in CRF, includes Visual Studio and Windows, free copies == VMWare == Find it in CRF, includes VMWare Fusion & Workstation == Dell == Student discount b8f54cfccc751010ab61015090ac87a639643c86 OpenSUSE 0 132 465 2015-11-27T04:50:11Z Nuk 25 以“列一下openSUSE包管理常见的命令 = 列出一个package的文件列表 = * rpm -ql $PACKAGE_NAME = 给一个文件(夹),查询它属于哪个package = ...”为内容创建页面 wikitext text/x-wiki 列一下openSUSE包管理常见的命令 = 列出一个package的文件列表 = * rpm -ql $PACKAGE_NAME = 给一个文件(夹),查询它属于哪个package = * rpm -qf $FILE_NAME 55e469b6ee998847416c8303d4b1d16979d6968b OpenSUSE 0 132 466 465 2015-11-27T04:50:27Z Nuk 25 wikitext text/x-wiki 列一下openSUSE包管理常见的命令 == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME f966b37f4472a7776560e43b5e449f87d3f9ba8a 467 466 2015-11-27T04:51:21Z Nuk 25 wikitext text/x-wiki 列一下openSUSE包管理和系统管理常见的命令 = Systemd = = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME 7ac7232918703f562af5d028e8bafa70dffd1f88 468 467 2015-11-27T04:54:30Z Nuk 25 /* Systemd */ wikitext text/x-wiki 列一下openSUSE包管理和系统管理常见的命令 = Systemd = == unit路径 == * 软件包的unit路径 /usr/lib/systemd/system /usr/lib/systemd/user * Administrator的unit路径 /etc/systemd/system /etc/systemd/user * 用户个人的unit $HOME/.config/systemd/user/ = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME d231aae4046191599b936c1e66f150a0c4f65ea9 469 468 2015-11-27T04:55:14Z Nuk 25 wikitext text/x-wiki 列一下openSUSE包管理和系统管理常见的命令 = Systemd = == unit路径 == * 软件包的unit路径 /usr/lib/systemd/system /usr/lib/systemd/user * Administrator的unit路径 /etc/systemd/system /etc/systemd/user * 用户个人的unit $HOME/.config/systemd/user/ = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 显示所有找不到源的包 == * zypper package --orphan 4839be4b1fc96669244a4f4ebcb2bb25856a7dff 470 469 2015-11-27T04:55:44Z Nuk 25 /* 显示所有找不到源的包 */ wikitext text/x-wiki 列一下openSUSE包管理和系统管理常见的命令 = Systemd = == unit路径 == * 软件包的unit路径 /usr/lib/systemd/system /usr/lib/systemd/user * Administrator的unit路径 /etc/systemd/system /etc/systemd/user * 用户个人的unit $HOME/.config/systemd/user/ = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 显示所有找不到源的包 == * zypper pkg --orphan 0f286ef2c59bdcbe482a082385e3086bbb6f18b5 471 470 2015-11-27T05:02:14Z Nuk 25 /* Zypper */ wikitext text/x-wiki 列一下openSUSE包管理和系统管理常见的命令 = Systemd = == unit路径 == * 软件包的unit路径 /usr/lib/systemd/system /usr/lib/systemd/user * Administrator的unit路径 /etc/systemd/system /etc/systemd/user * 用户个人的unit $HOME/.config/systemd/user/ = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 添加一个源 == * zypper ar -f $URL $ALIAS == 显示所有找不到源的包 == * zypper pkg --orphan f812e4d737b16247647f568e76644f148e78cf7f 476 471 2015-11-27T22:58:50Z Nuk 25 /* Zypper */ wikitext text/x-wiki 列一下openSUSE包管理和系统管理常见的命令 = Systemd = == unit路径 == * 软件包的unit路径 /usr/lib/systemd/system /usr/lib/systemd/user * Administrator的unit路径 /etc/systemd/system /etc/systemd/user * 用户个人的unit $HOME/.config/systemd/user/ = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 添加一个源 == * zypper ar -f $URL $ALIAS == zypper删除一个Application == * zypper rm -t Application $APP_NAME == 显示所有找不到源的包 == * zypper pkg --orphan 得到的结果不全 * zypper se -i |grep "System Packages" 这样应该是全的 dccf22bfae047f2e8d43d58c79e139b02cd7998c 477 476 2015-11-27T23:01:26Z Nuk 25 /* Zypper */ wikitext text/x-wiki 列一下openSUSE包管理和系统管理常见的命令 = Systemd = == unit路径 == * 软件包的unit路径 /usr/lib/systemd/system /usr/lib/systemd/user * Administrator的unit路径 /etc/systemd/system /etc/systemd/user * 用户个人的unit $HOME/.config/systemd/user/ = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 添加一个源 == * zypper ar -f $URL $ALIAS == zypper删除一个Application == * zypper rm -t Application $APP_NAME 好像这样也删不掉,原因不明。 == 显示所有找不到源的包 == * zypper pkg --orphan 得到的结果不全 * zypper se -i |grep "System Packages" 这样应该是全的 9b9527bf51dcf0e2d8f2bae4248149ee424bdf05 478 477 2015-11-28T22:40:10Z Nuk 25 /* Zypper */ wikitext text/x-wiki 列一下openSUSE包管理和系统管理常见的命令 = Systemd = == unit路径 == * 软件包的unit路径 /usr/lib/systemd/system /usr/lib/systemd/user * Administrator的unit路径 /etc/systemd/system /etc/systemd/user * 用户个人的unit $HOME/.config/systemd/user/ = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 添加一个源 == * zypper ar -f $URL $ALIAS == zypper删除一个Application == * zypper rm -t Application $APP_NAME zypper rm application:$APP_NAME 如果这样删不掉的话,这个命令可以告诉我们这个Application中包含哪些package。 我们需要先删除这个Application中包含的package,然后再删除这个application。 == 显示所有找不到源的包 == * zypper pkg --orphan 得到的结果不全 * zypper se -i |grep "System Packages" 这样应该是全的 * zypper pkg --unneeded 显示所有没有任何dependency的包(不被其他任何包依赖)。 64c5b520189425a2cd6b43e032ce66e863a238bc 479 478 2015-11-28T23:17:35Z Nuk 25 /* Zypper */ wikitext text/x-wiki 列一下openSUSE包管理和系统管理常见的命令 = Systemd = == unit路径 == * 软件包的unit路径 /usr/lib/systemd/system /usr/lib/systemd/user * Administrator的unit路径 /etc/systemd/system /etc/systemd/user * 用户个人的unit $HOME/.config/systemd/user/ = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 添加一个源 == * zypper ar -f $URL $ALIAS == zypper删除一个Application == * zypper rm -t Application $APP_NAME zypper rm application:$APP_NAME 如果这样删不掉的话,这个命令可以告诉我们这个Application中包含哪些package。 我们需要先删除这个Application中包含的package,然后再删除这个application。 == 显示所有找不到源的包 == * zypper pkg --orphan 得到的结果不全 * zypper se -i |grep "System Packages" 这样应该是全的 * zypper pkg --unneeded 显示所有没有任何dependency的包(不被其他任何包依赖)。 == zypper中Application的xml文件位置(以Dolphin为例) == /usr/share/appdata/dolphin.appdata.xml 6c80c413baf3844378259c287cb6e24a011dab54 480 479 2015-11-29T00:20:45Z Nuk 25 /* RPM */ wikitext text/x-wiki 列一下openSUSE包管理和系统管理常见的命令 = Systemd = == unit路径 == * 软件包的unit路径 /usr/lib/systemd/system /usr/lib/systemd/user * Administrator的unit路径 /etc/systemd/system /etc/systemd/user * 用户个人的unit $HOME/.config/systemd/user/ = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 查询一个package的dependency == * rpm -qR $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 添加一个源 == * zypper ar -f $URL $ALIAS == zypper删除一个Application == * zypper rm -t Application $APP_NAME zypper rm application:$APP_NAME 如果这样删不掉的话,这个命令可以告诉我们这个Application中包含哪些package。 我们需要先删除这个Application中包含的package,然后再删除这个application。 == 显示所有找不到源的包 == * zypper pkg --orphan 得到的结果不全 * zypper se -i |grep "System Packages" 这样应该是全的 * zypper pkg --unneeded 显示所有没有任何dependency的包(不被其他任何包依赖)。 == zypper中Application的xml文件位置(以Dolphin为例) == /usr/share/appdata/dolphin.appdata.xml 6b74bd9add8350fc1a4049b66e77cfa44d3285b3 482 480 2015-11-29T00:58:18Z Nuk 25 wikitext text/x-wiki 列一下openSUSE包管理和系统管理常见的命令 = Systemd = == unit路径 == * 软件包的unit路径 /usr/lib/systemd/system /usr/lib/systemd/user * Administrator的unit路径 /etc/systemd/system /etc/systemd/user * 用户个人的unit $HOME/.config/systemd/user/ = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 查询一个package的dependency == * rpm -qR $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 添加一个源 == * zypper ar -f $URL $ALIAS == zypper删除一个Application == * zypper rm -t Application $APP_NAME zypper rm application:$APP_NAME 如果这样删不掉的话,这个命令可以告诉我们这个Application中包含哪些package。 我们需要先删除这个Application中包含的package,然后再删除这个application。 == 显示所有找不到源的包 == * zypper pkg --orphan 得到的结果不全 * zypper se -i |grep "System Packages" 这样应该是全的 * zypper pkg --unneeded 显示所有没有任何dependency的包(不被其他任何包依赖)。 == zypper中Application的xml文件位置(以Dolphin为例) == /usr/share/appdata/dolphin.appdata.xml = OBS = [[OBS]] 1f3e53c0e060d0cbb5326a19f0cc8e7fad0468b0 483 482 2015-11-29T00:59:03Z Nuk 25 wikitext text/x-wiki 列一下openSUSE包管理和系统管理常见的命令 = Systemd = == unit路径 == * 软件包的unit路径 /usr/lib/systemd/system /usr/lib/systemd/user * Administrator的unit路径 /etc/systemd/system /etc/systemd/user * 用户个人的unit $HOME/.config/systemd/user/ = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 查询一个package的dependency == * rpm -qR $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 添加一个源 == * zypper ar -f $URL $ALIAS == zypper删除一个Application == * zypper rm -t Application $APP_NAME zypper rm application:$APP_NAME 如果这样删不掉的话,这个命令可以告诉我们这个Application中包含哪些package。 我们需要先删除这个Application中包含的package,然后再删除这个application。 == 显示所有找不到源的包 == * zypper pkg --orphan 得到的结果不全 * zypper se -i |grep "System Packages" 这样应该是全的 * zypper pkg --unneeded 显示所有没有任何dependency的包(不被其他任何包依赖)。 == zypper中Application的xml文件位置(以Dolphin为例) == /usr/share/appdata/dolphin.appdata.xml = OBS = [[OBS]] = Grub = [[suse_grub]] 85588937a3f87e83cb7256965ed3dcb63a05f9f5 484 483 2015-11-29T00:59:26Z Nuk 25 /* Grub */ wikitext text/x-wiki 列一下openSUSE包管理和系统管理常见的命令 = Systemd = == unit路径 == * 软件包的unit路径 /usr/lib/systemd/system /usr/lib/systemd/user * Administrator的unit路径 /etc/systemd/system /etc/systemd/user * 用户个人的unit $HOME/.config/systemd/user/ = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 查询一个package的dependency == * rpm -qR $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 添加一个源 == * zypper ar -f $URL $ALIAS == zypper删除一个Application == * zypper rm -t Application $APP_NAME zypper rm application:$APP_NAME 如果这样删不掉的话,这个命令可以告诉我们这个Application中包含哪些package。 我们需要先删除这个Application中包含的package,然后再删除这个application。 == 显示所有找不到源的包 == * zypper pkg --orphan 得到的结果不全 * zypper se -i |grep "System Packages" 这样应该是全的 * zypper pkg --unneeded 显示所有没有任何dependency的包(不被其他任何包依赖)。 == zypper中Application的xml文件位置(以Dolphin为例) == /usr/share/appdata/dolphin.appdata.xml = OBS = [[OBS]] = Grub = [[Suse_grub]] e7d69730974ce7545415ecd1f208321f7fb008dd 485 484 2015-11-29T00:59:38Z Nuk 25 /* Grub */ wikitext text/x-wiki 列一下openSUSE包管理和系统管理常见的命令 = Systemd = == unit路径 == * 软件包的unit路径 /usr/lib/systemd/system /usr/lib/systemd/user * Administrator的unit路径 /etc/systemd/system /etc/systemd/user * 用户个人的unit $HOME/.config/systemd/user/ = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 查询一个package的dependency == * rpm -qR $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 添加一个源 == * zypper ar -f $URL $ALIAS == zypper删除一个Application == * zypper rm -t Application $APP_NAME zypper rm application:$APP_NAME 如果这样删不掉的话,这个命令可以告诉我们这个Application中包含哪些package。 我们需要先删除这个Application中包含的package,然后再删除这个application。 == 显示所有找不到源的包 == * zypper pkg --orphan 得到的结果不全 * zypper se -i |grep "System Packages" 这样应该是全的 * zypper pkg --unneeded 显示所有没有任何dependency的包(不被其他任何包依赖)。 == zypper中Application的xml文件位置(以Dolphin为例) == /usr/share/appdata/dolphin.appdata.xml = OBS = [[OBS]] = Grub = [[Suse grub]] a5fdd670c35947a5fed44435f202771382575200 486 485 2015-11-29T01:00:54Z Nuk 25 wikitext text/x-wiki 列一下openSUSE系统管理常见的命令 [[suse_grub]] [[obs]] = Systemd = == unit路径 == * 软件包的unit路径 /usr/lib/systemd/system /usr/lib/systemd/user * Administrator的unit路径 /etc/systemd/system /etc/systemd/user * 用户个人的unit $HOME/.config/systemd/user/ = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 查询一个package的dependency == * rpm -qR $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 添加一个源 == * zypper ar -f $URL $ALIAS == zypper删除一个Application == * zypper rm -t Application $APP_NAME zypper rm application:$APP_NAME 如果这样删不掉的话,这个命令可以告诉我们这个Application中包含哪些package。 我们需要先删除这个Application中包含的package,然后再删除这个application。 == 显示所有找不到源的包 == * zypper pkg --orphan 得到的结果不全 * zypper se -i |grep "System Packages" 这样应该是全的 * zypper pkg --unneeded 显示所有没有任何dependency的包(不被其他任何包依赖)。 == zypper中Application的xml文件位置(以Dolphin为例) == /usr/share/appdata/dolphin.appdata.xml = OBS = [[OBS]] = Grub = [[Suse grub]] 513d9aa8efe568e31df43aaf30281a7eb22bd0bf 487 486 2015-11-29T01:01:09Z Nuk 25 wikitext text/x-wiki 列一下openSUSE系统管理常见的命令 [[Suse_grub]] [[OBS]] = Systemd = == unit路径 == * 软件包的unit路径 /usr/lib/systemd/system /usr/lib/systemd/user * Administrator的unit路径 /etc/systemd/system /etc/systemd/user * 用户个人的unit $HOME/.config/systemd/user/ = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 查询一个package的dependency == * rpm -qR $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 添加一个源 == * zypper ar -f $URL $ALIAS == zypper删除一个Application == * zypper rm -t Application $APP_NAME zypper rm application:$APP_NAME 如果这样删不掉的话,这个命令可以告诉我们这个Application中包含哪些package。 我们需要先删除这个Application中包含的package,然后再删除这个application。 == 显示所有找不到源的包 == * zypper pkg --orphan 得到的结果不全 * zypper se -i |grep "System Packages" 这样应该是全的 * zypper pkg --unneeded 显示所有没有任何dependency的包(不被其他任何包依赖)。 == zypper中Application的xml文件位置(以Dolphin为例) == /usr/share/appdata/dolphin.appdata.xml = OBS = [[OBS]] = Grub = [[Suse grub]] 41c3d9c17336f617ba03f34743b50e4c21d30187 490 487 2015-11-29T01:09:17Z Nuk 25 wikitext text/x-wiki 列一下openSUSE系统管理常见的命令 [[Suse_grub]] [[OBS]] = Systemd = == unit路径 == * 软件包的unit路径 /usr/lib/systemd/system /usr/lib/systemd/user * Administrator的unit路径 /etc/systemd/system /etc/systemd/user * 用户个人的unit $HOME/.config/systemd/user/ = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 查询一个package的dependency == * rpm -qR $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 添加一个源 == * zypper ar -f $URL $ALIAS == zypper删除一个Application == * zypper rm -t Application $APP_NAME zypper rm application:$APP_NAME 如果这样删不掉的话,这个命令可以告诉我们这个Application中包含哪些package。 我们需要先删除这个Application中包含的package,然后再删除这个application。 == 显示所有找不到源的包 == * zypper pkg --orphan 得到的结果不全 * zypper se -i |grep "System Packages" 这样应该是全的 * zypper pkg --unneeded 显示所有没有任何dependency的包(不被其他任何包依赖)。 == zypper中Application的xml文件位置(以Dolphin为例) == /usr/share/appdata/dolphin.appdata.xml 32d2134221b9d7f75118a8647184741fddea3ff2 495 490 2015-11-29T02:49:21Z Nuk 25 wikitext text/x-wiki 列一下openSUSE系统管理常见的命令 [[Suse_grub]] [[OBS]] [[Systemd]] = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 查询一个package的dependency == * rpm -qR $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 添加一个源 == * zypper ar -f $URL $ALIAS == zypper删除一个Application == * zypper rm -t Application $APP_NAME zypper rm application:$APP_NAME 如果这样删不掉的话,这个命令可以告诉我们这个Application中包含哪些package。 我们需要先删除这个Application中包含的package,然后再删除这个application。 == 显示所有找不到源的包 == * zypper pkg --orphan 得到的结果不全 * zypper se -i |grep "System Packages" 这样应该是全的 * zypper pkg --unneeded 显示所有没有任何dependency的包(不被其他任何包依赖)。 == zypper中Application的xml文件位置(以Dolphin为例) == /usr/share/appdata/dolphin.appdata.xml 20c3ad7dcf22cb312e479f5bac96fe17adc37bcc 496 495 2015-11-29T02:49:32Z Nuk 25 wikitext text/x-wiki 列一下openSUSE系统管理常见的命令 [[Suse_grub]] [[OBS]] [[Suse_systemd]] = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 查询一个package的dependency == * rpm -qR $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 添加一个源 == * zypper ar -f $URL $ALIAS == zypper删除一个Application == * zypper rm -t Application $APP_NAME zypper rm application:$APP_NAME 如果这样删不掉的话,这个命令可以告诉我们这个Application中包含哪些package。 我们需要先删除这个Application中包含的package,然后再删除这个application。 == 显示所有找不到源的包 == * zypper pkg --orphan 得到的结果不全 * zypper se -i |grep "System Packages" 这样应该是全的 * zypper pkg --unneeded 显示所有没有任何dependency的包(不被其他任何包依赖)。 == zypper中Application的xml文件位置(以Dolphin为例) == /usr/share/appdata/dolphin.appdata.xml e78175f51470a5429642be4c35dfc139c850007b 497 496 2015-12-05T05:36:38Z Nuk 25 wikitext text/x-wiki 列一下openSUSE系统管理常见的命令 [[magit]] [[Suse_grub]] [[OBS]] [[Suse_systemd]] = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 查询一个package的dependency == * rpm -qR $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 添加一个源 == * zypper ar -f $URL $ALIAS == zypper删除一个Application == * zypper rm -t Application $APP_NAME zypper rm application:$APP_NAME 如果这样删不掉的话,这个命令可以告诉我们这个Application中包含哪些package。 我们需要先删除这个Application中包含的package,然后再删除这个application。 == 显示所有找不到源的包 == * zypper pkg --orphan 得到的结果不全 * zypper se -i |grep "System Packages" 这样应该是全的 * zypper pkg --unneeded 显示所有没有任何dependency的包(不被其他任何包依赖)。 == zypper中Application的xml文件位置(以Dolphin为例) == /usr/share/appdata/dolphin.appdata.xml 6f7db2017c1fa2b150621934fae82f504ee7f792 502 497 2015-12-07T05:35:24Z Nuk 25 wikitext text/x-wiki 列一下openSUSE系统管理常见的命令 [[magit]] [[Suse_grub]] [[OBS]] [[Suse_systemd]] = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 查询一个package的dependency == * rpm -qR $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 添加一个源 == * zypper ar -f $URL $ALIAS == zypper删除一个Application == * zypper rm -t Application $APP_NAME zypper rm application:$APP_NAME 如果这样删不掉的话,这个命令可以告诉我们这个Application中包含哪些package。 我们需要先删除这个Application中包含的package,然后再删除这个application。 == 显示所有找不到源的包 == * zypper pkg --orphan 得到的结果不全 * zypper se -i |grep "System Packages" 这样应该是全的 * zypper pkg --unneeded 显示所有没有任何dependency的包(不被其他任何包依赖)。 == zypper中Application的xml文件位置(以Dolphin为例) == /usr/share/appdata/dolphin.appdata.xml = Ghostscript = == 去pdf密码 == gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=unencrypted.pdf -c .setpdfwrite -f encrypted.pdf feb0433d35f18d2bf2941ead1ef25106727cf2f9 507 502 2015-12-25T02:12:31Z Nuk 25 wikitext text/x-wiki 列一下openSUSE系统管理常见的命令 [[magit]] [[Suse_grub]] [[OBS]] [[Suse_systemd]] [[pdftotext]] = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 查询一个package的dependency == * rpm -qR $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 添加一个源 == * zypper ar -f $URL $ALIAS == zypper删除一个Application == * zypper rm -t Application $APP_NAME zypper rm application:$APP_NAME 如果这样删不掉的话,这个命令可以告诉我们这个Application中包含哪些package。 我们需要先删除这个Application中包含的package,然后再删除这个application。 == 显示所有找不到源的包 == * zypper pkg --orphan 得到的结果不全 * zypper se -i |grep "System Packages" 这样应该是全的 * zypper pkg --unneeded 显示所有没有任何dependency的包(不被其他任何包依赖)。 == zypper中Application的xml文件位置(以Dolphin为例) == /usr/share/appdata/dolphin.appdata.xml = Ghostscript = == 去pdf密码 == gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=unencrypted.pdf -c .setpdfwrite -f encrypted.pdf 7cd167696b8c287d51047354c0093d8ae1c27fed OBS 0 133 472 2015-11-27T16:01:21Z Nuk 25 以“本页保存一些Open Build System使用记录。”为内容创建页面 wikitext text/x-wiki 本页保存一些Open Build System使用记录。 ad0f02cfc4fe8173e3478f79132ee3c44d92f329 473 472 2015-11-27T16:43:09Z Nuk 25 wikitext text/x-wiki 本页保存一些Open Build System使用记录。 = osc 常用命令 = b6afc51d17704bd2024ac440fbeaa56ba5d974a7 474 473 2015-11-27T16:44:52Z Nuk 25 /* osc 常用命令 */ wikitext text/x-wiki 本页保存一些Open Build System使用记录。 = osc 常用命令 = == 修改project的build target == osc meta prj -e home:nuklly == 修改project中某个package的metadata == osc meta pkg -e home:nuklly hplip e98d8eed28bfe14628c909cc56167650c18a8c21 475 474 2015-11-27T18:18:49Z Nuk 25 /* osc 常用命令 */ wikitext text/x-wiki 本页保存一些Open Build System使用记录。 = osc 常用命令 = == 修改project的build target == osc meta prj -e home:nuklly == 修改project中某个package的metadata == osc meta pkg -e home:nuklly hplip == 删除project中的一个package == osc rdelete <package> 8fa54c28bb3e255cc0f871e0ff3afa4151e36c00 504 475 2015-12-14T17:27:43Z Nuk 25 wikitext text/x-wiki 本页保存一些Open Build System使用记录。 = RPM 宏定义查询 = * RPM Macros /usr/lib/rpm/macros * RPM KDE4 Macros /etc/macros/macros.kde4 = osc 常用命令 = == 修改project的build target == osc meta prj -e home:nuklly == 修改project中某个package的metadata == osc meta pkg -e home:nuklly hplip == 删除project中的一个package == osc rdelete <package> c111ea3796698bd36553266bab7ab5d303b4c43b 505 504 2015-12-14T17:27:55Z Nuk 25 /* RPM 宏定义查询 */ wikitext text/x-wiki 本页保存一些Open Build System使用记录。 = RPM 宏定义查询 = * RPM Macros - /usr/lib/rpm/macros * RPM KDE4 Macros - /etc/macros/macros.kde4 = osc 常用命令 = == 修改project的build target == osc meta prj -e home:nuklly == 修改project中某个package的metadata == osc meta pkg -e home:nuklly hplip == 删除project中的一个package == osc rdelete <package> d7e4901726d162d9de6fc86936f616385368b489 506 505 2015-12-14T17:28:21Z Nuk 25 /* osc 常用命令 */ wikitext text/x-wiki 本页保存一些Open Build System使用记录。 = RPM 宏定义查询 = * RPM Macros - /usr/lib/rpm/macros * RPM KDE4 Macros - /etc/macros/macros.kde4 = osc 常用命令 = * 修改project的build target - osc meta prj -e home:nuklly * 修改project中某个package的metadata - osc meta pkg -e home:nuklly hplip * 删除project中的一个package - osc rdelete <package> 08099859383add59c419f3a811fe10b76da2866b 首页 0 1 481 353 2015-11-29T00:57:58Z Nuk 25 wikitext text/x-wiki [[SubsConscious]] [[:Category:脚本|Scripts]] [[Package Management]] [[Startup Management]] [[Git Cheatsheet]] [[BBS Project]] [[openSUSE]] <!-- == 入门 == * [http://www.mediawiki.org/wiki/Manual:Configuration_settings MediaWiki 配置设置列表] * [http://www.mediawiki.org/wiki/Manual:FAQ/zh-hans MediaWiki常见问题] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki发布邮件列表] --> b4f1c0a5200753e80909ec75154c835312449edb Suse grub 0 134 488 2015-11-29T01:05:19Z Nuk 25 以“suse默认使用grub2作为bootloader = /etc/sysconfig/boot = * PROMPT_FOR_CONFIRM="no" * CONFIRM_PROMPT_TIMEOUT="5" 默认等待用户回答进入系统选项的...”为内容创建页面 wikitext text/x-wiki suse默认使用grub2作为bootloader = /etc/sysconfig/boot = * PROMPT_FOR_CONFIRM="no" * CONFIRM_PROMPT_TIMEOUT="5" 默认等待用户回答进入系统选项的时间 = /etc/sysconfig/bootloader = * LOADER_TYPE="grub2" = /etc/default/grub = 改动此文件后, 运行 'grub2-mkconfig -o /boot/grub2/grub.cfg' 来更新grub2配置。 * GRUB_DISTRIBUTOR="openSUSE Tumbleweed" 发行版名称 4a129df6526a09bc94b88dc9a3edaee37e8a5b60 489 488 2015-11-29T01:07:48Z Nuk 25 /* /etc/default/grub */ wikitext text/x-wiki suse默认使用grub2作为bootloader = /etc/sysconfig/boot = * PROMPT_FOR_CONFIRM="no" * CONFIRM_PROMPT_TIMEOUT="5" 默认等待用户回答进入系统选项的时间 = /etc/sysconfig/bootloader = * LOADER_TYPE="grub2" = /etc/default/grub = 改动此文件后, 运行 'grub2-mkconfig -o /boot/grub2/grub.cfg' 来更新grub2配置。 * GRUB_DISTRIBUTOR="openSUSE Tumbleweed" 设置发行版名称 * GRUB_THEME=/boot/grub2/themes/openSUSE/theme.txt * GRUB_BACKGROUND=/boot/grub2/themes/openSUSE/background.png 设置Grub背景图片和主题。 f3367fbf6e9d3d7b134a51660a87831603483d2b Suse systemd 0 135 491 2015-11-29T02:43:39Z Nuk 25 以“ = 用户自定义服务 = * Unit位置 ~/.config/systemd/user/ * 开机自动启动服务 systemctl --user enable XXX.service * 更新服务文件后重新载...”为内容创建页面 wikitext text/x-wiki = 用户自定义服务 = * Unit位置 ~/.config/systemd/user/ * 开机自动启动服务 systemctl --user enable XXX.service * 更新服务文件后重新载入 systemctl --user daemon-reload 88c25563605aaf93c9deed79d5b4bb99e7f48768 492 491 2015-11-29T02:45:49Z Nuk 25 /* 用户自定义服务 */ wikitext text/x-wiki = 用户个人自定义服务 = * Unit位置 ~/.config/systemd/user/ * 开机自动启动服务 systemctl --user enable XXX.service * 更新服务文件后重新载入 systemctl --user daemon-reload * 查看服务状态 systemctl --user status XXX.service be45c4359a9a4d16e33efb21d2747994cc1b4186 493 492 2015-11-29T02:47:52Z Nuk 25 /* 用户个人自定义服务 */ wikitext text/x-wiki = 用户个人服务 = * Unit位置 ~/.config/systemd/user/ * 开机自动启动服务 systemctl --user enable XXX.service * 更新服务文件后重新载入 systemctl --user daemon-reload * 查看服务状态 systemctl --user status XXX.service 4670ee8d752851ac6244ed96a6e77a042e6f015f 494 493 2015-11-29T02:48:56Z Nuk 25 wikitext text/x-wiki = 用户个人服务 = * Unit位置 ~/.config/systemd/user/ * 开机自动启动服务 systemctl --user enable XXX.service * 更新服务文件后重新载入 systemctl --user daemon-reload * 查看服务状态 systemctl --user status XXX.service = unit路径 = * 软件包的unit路径 /usr/lib/systemd/system /usr/lib/systemd/user * Administrator的unit路径 /etc/systemd/system /etc/systemd/user * 用户个人的unit路径 $HOME/.config/systemd/user/ 340fa88f4c857a7f931ca9edad29aec33c60845f Magit 0 136 498 2015-12-05T05:41:42Z Nuk 25 以“= Remote Management = * magit-remote-set-url = Commit = * C-u S Commit everything, including untracked files.”为内容创建页面 wikitext text/x-wiki = Remote Management = * magit-remote-set-url = Commit = * C-u S Commit everything, including untracked files. 472464b86e965bc78e14206187680d490fcf7927 Upgrade Cheatsheet 0 137 499 2015-12-06T01:30:56Z HenryHu 1 以“== FreeBSD == === Ports Upgrade === 1. pkg upgrade 2. cd /usr/ports && svn up 3. make fetchindex 4. ~/scripts/updlocked.sh === Source Upgrade === 1. cd /usr/src 2....”为内容创建页面 wikitext text/x-wiki == FreeBSD == === Ports Upgrade === 1. pkg upgrade 2. cd /usr/ports && svn up 3. make fetchindex 4. ~/scripts/updlocked.sh === Source Upgrade === 1. cd /usr/src 2. svn up 3. make kernel 4. reboot 5. make buildworld 6. make installworld 7. mergemaster == Debian / Ubuntu == 1. apt-get dist-upgrade == Arch == 1. pacman -Sy 2. pacman -Su 5c203eb0f41578783a89b7a6d8311d1534521e8f 500 499 2015-12-06T01:31:55Z HenryHu 1 /* FreeBSD */ wikitext text/x-wiki == FreeBSD == === Ports Upgrade === # pkg upgrade # cd /usr/ports && svn up # make fetchindex # ~/scripts/updlocked.sh === Source Upgrade === # cd /usr/src # svn up # make kernel # reboot # make buildworld # make installworld # mergemaster == Debian / Ubuntu == 1. apt-get dist-upgrade == Arch == 1. pacman -Sy 2. pacman -Su fddbf63b6017b47d4dc07af8c32512f5d05615bd 501 500 2015-12-06T01:32:54Z HenryHu 1 wikitext text/x-wiki == FreeBSD == === Ports Upgrade === # pkg upgrade # cd /usr/ports && svn up # make fetchindex # ~/scripts/updlocked.sh === Source Upgrade === # cd /usr/src # svn up # make kernel # reboot # make buildworld # make installworld # mergemaster == Debian / Ubuntu == === Software Update === # apt-get dist-upgrade === System Update === # do-release-upgrade == Arch == # pacman -Sy # pacman -Su 5ffdf6146c149a735a2d93a8387165aa9ec278c3 Splitape 0 18 503 42 2015-12-08T00:58:49Z HenryHu 1 wikitext text/x-wiki [[Category:脚本]] splitape最早是用来分割APE文件的,现在稍微经过扩展,各种文件都能分割。 割完了能转成FLAC或其他格式,并且根据metadata进行命名,之后用easytag处理一下就能内嵌metadata了,例如id3v2或者flac的tag之类。 用到了[[shntool]]。 == 关于TAK == TAK这个格式很少出现,但是碰见了还是麻烦。最简单的处理方法是下载TAK for windows,扔到某个目录,然后写个脚本,链接成takc: <source lang="bash"> wine /home/henryhu/soft/tak/Applications/Takc.exe $* </source> shntool会自己找takc,所以这样就行了。 == 关于编码 == 看来真该用个自动编码检测器…… == code == <source lang="bash"> #!/bin/sh if [ $# -le 1 ]; then echo "This tool would split ape file to flac file(s) according to cue sheet." echo "You may also specify other formats." echo "usage: $0 <cue file name> <ape file name> [<output format>]" exit 1 fi CUEFILE="$1" FILETYPE=`file "$1"` PA=`echo $FILETYPE | grep "ISO-8859"` PB=`echo $FILETYPE | grep "extended-ASCII"` PC=`echo $FILETYPE | grep "Non-ISO"` if [ "$PA" != "" -o "$PB" != "" -o "$PC" != "" ]; then echo "Found non-UTF8 CUE file." echo "=== 1.GBK ===" cat "$1" | iconv -f gbk | head echo "=== 2.CP932 ===" cat "$1" | iconv -f cp932 | head echo "Which one? 1=gbk 2=cp932" read encoding_id if [ "$encoding_id" = "1" ]; then encoding=gbk else encoding=cp932 fi echo "Found $encoding CUE file, converting..." cat "$1" | iconv -f $encoding > /tmp/splitape.cue.tmp CUEFILE=/tmp/splitape.cue.tmp fi if [ "$3" = "" ]; then OUTPUT_FORMAT="flac" elif [ "$3" = "mp3" ]; then OUTPUT_FORMAT="cust ext=mp3 lame - %f" else OUTPUT_FORMAT=$3 fi echo "CUE File: $1" echo "APE File: $2" shntool split -f "$CUEFILE" -t %n_%p_%a_%t -o "$OUTPUT_FORMAT" "$2" </source> fb533e7009156cc82730b8844dd051f07b47ed0c Pdftotext 0 138 508 2015-12-25T02:12:54Z Nuk 25 以“= pdftotext = 从pdf中提取text。”为内容创建页面 wikitext text/x-wiki = pdftotext = 从pdf中提取text。 87f3908705369d82aa5748d25252287268f9e549 509 508 2015-12-25T02:49:38Z Nuk 25 /* pdftotext */ wikitext text/x-wiki 从pdf中提取text。 = 用法 = * pdftotext A.pdf a.txt 将pdf转换成txt文件。 8fda0314ce8a123039dd7171a5d1e4cbf08051ff Twitter Clients 0 139 510 2015-12-26T05:14:12Z HenryHu 1 以“{| class="wikitable" |- ! Software ! Images preview ! Quoted tweets ! Retweets ! Misc problems |- | Turpial | Fine | Good | Good | |- | Choqok | | | Ok, not showin...”为内容创建页面 wikitext text/x-wiki {| class="wikitable" |- ! Software ! Images preview ! Quoted tweets ! Retweets ! Misc problems |- | Turpial | Fine | Good | Good | |- | Choqok | | | Ok, not showing the original author's avatar |- | Hotot | | | | Memory leak |- | Twidere | Good, supports multiple images | Good | Good |} 533ca32cb346c8b95259f3431513dc5eeb413af6 511 510 2015-12-26T05:22:16Z HenryHu 1 wikitext text/x-wiki {| class="wikitable" |- ! Software ! Version ! Images preview ! Quoted tweets ! Retweets ! Conversation ! Misc problems |- | Turpial | Git | Fine | Good | Good | Good | |- | Choqok | 1.5 | Fine | No | Ok, not showing the original author's avatar | No | |- | Hotot | 0.9.8.15 | Fine | No | Good | Good | Memory leak |- | Twidere | Latest | Good, supports multiple images | Good | Good | Good | |} 52c74b3c8991fbda787f40449751fa027fcfeb8f Cmake 0 140 512 2016-01-22T21:51:58Z HenryHu 1 以“== Build debug/release version * Debug version: cmake [args] -DCMAKE_BUILD_TYPE=Debug * Release version: cmake [args] -DCMAKE_BUILD_TYPE=Release”为内容创建页面 wikitext text/x-wiki == Build debug/release version * Debug version: cmake [args] -DCMAKE_BUILD_TYPE=Debug * Release version: cmake [args] -DCMAKE_BUILD_TYPE=Release 8d068eee396b322e3cd9106cdcfe2c9163f966ea 513 512 2016-01-22T21:52:06Z HenryHu 1 wikitext text/x-wiki == Build debug/release version == * Debug version: cmake [args] -DCMAKE_BUILD_TYPE=Debug * Release version: cmake [args] -DCMAKE_BUILD_TYPE=Release 77434dc8ff9304e243f28314191855030f09c0df Git Cheatsheet 0 79 514 218 2016-01-28T18:48:47Z HenryHu 1 wikitext text/x-wiki GIT CHEATSHEET! Ref: http://spheredev.org/wiki/Git_for_the_lazy Ref: https://makandracards.com/makandra/topics/version-control == 撤销上次 git commit == git reset --soft HEAD^ 如果你想把add进去的文件也撤销掉,变成没有add的状态: git reset <FILE> == 删除branch == 删除本地branch: git branch -d <branch name> 这个不会对远程的产生影响。只是你push/pull的时候,这个branch不会参与。 如果要删除远程branch: '''注意!注意!危险!''' git push origin :<branch name> 这样远端这个branch会被干掉…… == export == mkdir <target dir> git archive master | tar -x -C <target dir> 4ac403891bda3a93e12299f880ffe705cbbe8adb Network emulation 0 141 515 2016-01-31T19:41:07Z HenryHu 1 以“From stackoverflow http://stackoverflow.com/questions/614795/simulate-delayed-and-dropped-packets-on-linux netem leverages functionality already built into Linux an...”为内容创建页面 wikitext text/x-wiki From stackoverflow http://stackoverflow.com/questions/614795/simulate-delayed-and-dropped-packets-on-linux netem leverages functionality already built into Linux and userspace utilities to simulate networks. This is actually what Mark's answer refers to, by a different name. The examples on their homepage already show how you can achieve what you've asked for: Examples == Emulating wide area network delays == This is the simplest example, it just adds a fixed amount of delay to all packets going out of the local Ethernet. # tc qdisc add dev eth0 root netem delay 100ms Now a simple ping test to host on the local network should show an increase of 100 milliseconds. The delay is limited by the clock resolution of the kernel (Hz). On most 2.4 systems, the system clock runs at 100 Hz which allows delays in increments of 10 ms. On 2.6, the value is a configuration parameter from 1000 to 100 Hz. Later examples just change parameters without reloading the qdisc Real wide area networks show variability so it is possible to add random variation. # tc qdisc change dev eth0 root netem delay 100ms 10ms This causes the added delay to be 100 ± 10 ms. Network delay variation isn't purely random, so to emulate that there is a correlation value as well. # tc qdisc change dev eth0 root netem delay 100ms 10ms 25% This causes the added delay to be 100 ± 10 ms with the next random element depending 25% on the last one. This isn't true statistical correlation, but an approximation. === Delay distribution === Typically, the delay in a network is not uniform. It is more common to use a something like a normal distribution to describe the variation in delay. The netem discipline can take a table to specify a non-uniform distribution. # tc qdisc change dev eth0 root netem delay 100ms 20ms distribution normal The actual tables (normal, pareto, paretonormal) are generated as part of the iproute2 compilation and placed in /usr/lib/tc; so it is possible with some effort to make your own distribution based on experimental data. === Packet loss === Random packet loss is specified in the 'tc' command in percent. The smallest possible non-zero value is: 2−32 = 0.0000000232% # tc qdisc change dev eth0 root netem loss 0.1% This causes 1/10th of a percent (i.e. 1 out of 1000) packets to be randomly dropped. An optional correlation may also be added. This causes the random number generator to be less random and can be used to emulate packet burst losses. # tc qdisc change dev eth0 root netem loss 0.3% 25% This will cause 0.3% of packets to be lost, and each successive probability depends by a quarter on the last one. Probn = 0.25 × Probn-1 + 0.75 × Random Note that you should use tc qdisc add if you have no rules for that interface or tc qdisc change if you already have rules for that interface. Attempting to use tc qdisc change on an interface with no rules will give the error RTNETLINK answers: No such file or directory. e7932b3fc1e29db3812860d596e1421f7c10ee95 Mail system 0 142 516 2016-02-02T18:20:33Z HenryHu 1 以“== Flush postfix queue == First stop postfix, then sudo postsuper -d ALL”为内容创建页面 wikitext text/x-wiki == Flush postfix queue == First stop postfix, then sudo postsuper -d ALL 7ea529c1d243704139e8cdb6755dd682af6ee4dd Virtual Machines 0 143 517 2016-02-02T22:52:27Z HenryHu 1 以“ref: http://ostolc.org/kvm-clone-guests-from-template-image.html KVM - Clone Guests from Template Image virsh shutdown basevm dump its XML file to template.xm...”为内容创建页面 wikitext text/x-wiki ref: http://ostolc.org/kvm-clone-guests-from-template-image.html KVM - Clone Guests from Template Image virsh shutdown basevm dump its XML file to template.xml and copy its image to template.qcow2 virsh dumpxml basevm > /var/lib/libvirt/images/template.xml cp /var/lib/libvirt/images/basevm.qcow2 /var/lib/libvirt/images/template.qcow2 in template.xml point the disk source file to template.qcow2 <pre> <disk type='file' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source file='/var/lib/libvirt/images/template.qcow2'/> <target dev='vda' bus='virtio'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> </disk> </pre> run virt-sysprep on template.qcow2. This will reset the image, e.g. will remove the host SSH keys, will create new MAC address for network interfaces, adjust udev persistent net rules, clean up log files, etc... virt-sysprep -a /var/lib/libvirt/images/template.qcow2 after this poin you don't need the base VM anymore. Delete it. virsh undefine basevm rm /var/lib/libvirt/images/basevm.qcow2 Cloning new VMs from Template clone new VMs from template.xml and template.qcow2 virt-clone --connect qemu:///system \ --original-xml /var/lib/libvirt/images/template.xml \ --name newvm \ --file /var/lib/libvirt/images/newvm.qcow2 Done 8513de5cbba7238987b36988c3049d6e27429b78 518 517 2016-02-02T22:53:01Z HenryHu 1 wikitext text/x-wiki == Clone Guests from Template Image == ref: http://ostolc.org/kvm-clone-guests-from-template-image.html virsh shutdown basevm dump its XML file to template.xml and copy its image to template.qcow2 virsh dumpxml basevm > /var/lib/libvirt/images/template.xml cp /var/lib/libvirt/images/basevm.qcow2 /var/lib/libvirt/images/template.qcow2 in template.xml point the disk source file to template.qcow2 <pre> <disk type='file' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source file='/var/lib/libvirt/images/template.qcow2'/> <target dev='vda' bus='virtio'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> </disk> </pre> run virt-sysprep on template.qcow2. This will reset the image, e.g. will remove the host SSH keys, will create new MAC address for network interfaces, adjust udev persistent net rules, clean up log files, etc... virt-sysprep -a /var/lib/libvirt/images/template.qcow2 after this poin you don't need the base VM anymore. Delete it. virsh undefine basevm rm /var/lib/libvirt/images/basevm.qcow2 Cloning new VMs from Template clone new VMs from template.xml and template.qcow2 virt-clone --connect qemu:///system \ --original-xml /var/lib/libvirt/images/template.xml \ --name newvm \ --file /var/lib/libvirt/images/newvm.qcow2 Done 728338fed0c1dcb6b594aabd0f122eee0e3fe47b AndWell 0 85 519 305 2016-02-21T06:22:32Z HenryHu 1 /* Change Log */ wikitext text/x-wiki === Change Log === 0.3.3 * Move away from deprecated APIs * Check certificates. Now we have legit certificates. 0.3.2 * workaround a bug in Android 4.1-4.1.2 (#38770) 0.3.1 * bug fix 0.3.0 * Dual pane mode on large devices * Signature selection & randomization * Target new SDK (android 4.2, r17) * Chinese translation * Introduce Fragment for components 0.2.11 * workaround android 4.1 TextView bug (#35466) 0.2.10 * fix lists in filtered mode * get OAuth code automatically 0.2.9 * Bug fix: release connection for reuse 0.2.8 * Thread first 0.2.7 * Fix unread mark 0.2.6 * Limit timeout 0.2.5 * Various bug fix * Enhancement: Only refresh post list if necessary 0.2.4 * Enhancement: Persist connection 0.2.3 * Enhancement: Reply in view mode * Enhancement: Icons * Enhancement: Insert banner 0.2.2 * Bug fix: Stale busy dialog 0.2.1 * Enhancement: Show busy dialog when posting / replying * Enhancement: Save last qmd# 0.2 * New feature: Post * New feature: Reply 0.1.8 * Minor fix to support Google TV 0.1.7 * Minor modification to UI 0.1.6 * Initial release on the market * Require users to enter server's API address. 856f8a630129066fdad265b9ef99feab0f5bfd26 Isaac 0 144 520 2016-03-10T16:13:39Z HenryHu 1 以“== Offensive == * Quad shot + Explosive shot + Reusable fly generator ** Optional: Quick charge High DPS, flies have high damage. Most monsters killed by files, boss...”为内容创建页面 wikitext text/x-wiki == Offensive == * Quad shot + Explosive shot + Reusable fly generator ** Optional: Quick charge High DPS, flies have high damage. Most monsters killed by files, boss killed easily by attacks. == Defensive == * 3 x Pretty files ** Or replace one with meat cube Breaks most projectiles a513fd4f77f431c2f1673f242a5cf505cdbaeba2 521 520 2016-03-10T16:17:21Z HenryHu 1 /* Offensive */ wikitext text/x-wiki == Offensive == * Quad shot + Explosive shot + Reusable fly generator ** Optional: Quick charge High DPS, flies have high damage. Most monsters killed by files, boss killed easily by attacks. * Big shots + Max shot speed + Max shot damage Quickly resolve anything. == Improvements == * PhD + Miner's hat You can find many hidden rooms, and with PhD they have good pills. (Some hidden rooms contain many mushrooms, which contain pills) == Defensive == * 3 x Pretty files ** Or replace one with meat cube Breaks most projectiles 73d21f49c1ddd9b7a561cb5f2bfbb8b315ee3742 522 521 2016-03-11T06:31:19Z HenryHu 1 /* Offensive */ wikitext text/x-wiki == Offensive == * Quad shot + Explosive shot + Reusable fly generator ** Optional: Quick charge High DPS, flies have high damage. Most monsters killed by files, boss killed easily by attacks. * Big shots + Max shot speed + Max shot damage Quickly resolve anything. * Flood shot + Antigravity + Magnetic tears Creates a big shot ball, enemies are dragged into it and instantly killed. Even for bosses. Afterwards, the ball becomes a flood like normal flood attack. == Improvements == * PhD + Miner's hat You can find many hidden rooms, and with PhD they have good pills. (Some hidden rooms contain many mushrooms, which contain pills) == Defensive == * 3 x Pretty files ** Or replace one with meat cube Breaks most projectiles d79883fb909294aa62b5cd84f9abf831c1f5699c 523 522 2016-03-11T06:32:52Z HenryHu 1 /* Defensive */ wikitext text/x-wiki == Offensive == * Quad shot + Explosive shot + Reusable fly generator ** Optional: Quick charge High DPS, flies have high damage. Most monsters killed by files, boss killed easily by attacks. * Big shots + Max shot speed + Max shot damage Quickly resolve anything. * Flood shot + Antigravity + Magnetic tears Creates a big shot ball, enemies are dragged into it and instantly killed. Even for bosses. Afterwards, the ball becomes a flood like normal flood attack. == Improvements == * PhD + Miner's hat You can find many hidden rooms, and with PhD they have good pills. (Some hidden rooms contain many mushrooms, which contain pills) == Defensive == Offense is the best defense! * 3 x Pretty files ** Or replace one with meat cube Breaks most projectiles c74718e0b5cf9808e3b934c7e49388bfeb3c9958 OpenSUSE 0 132 524 507 2016-04-15T03:59:01Z Nuk 25 wikitext text/x-wiki 列一下openSUSE系统管理常见的命令 [[magit]] [[Suse_grub]] [[OBS]] [[Suse_systemd]] [[Suse_nvidia]] [[pdftotext]] = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 查询一个package的dependency == * rpm -qR $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 添加一个源 == * zypper ar -f $URL $ALIAS == zypper删除一个Application == * zypper rm -t Application $APP_NAME zypper rm application:$APP_NAME 如果这样删不掉的话,这个命令可以告诉我们这个Application中包含哪些package。 我们需要先删除这个Application中包含的package,然后再删除这个application。 == 显示所有找不到源的包 == * zypper pkg --orphan 得到的结果不全 * zypper se -i |grep "System Packages" 这样应该是全的 * zypper pkg --unneeded 显示所有没有任何dependency的包(不被其他任何包依赖)。 == zypper中Application的xml文件位置(以Dolphin为例) == /usr/share/appdata/dolphin.appdata.xml = Ghostscript = == 去pdf密码 == gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=unencrypted.pdf -c .setpdfwrite -f encrypted.pdf 9f96aded35ff623ce8bac708d5b6c477f61d090a Suse nvidia 0 145 525 2016-04-15T04:05:54Z Nuk 25 以“= openSUSE Tumbleweed NVidia 闭源驱动安装使用指南 = 适用linux版本:4.5.0 适用nvidia驱动版本:361.42 == 文件位置 == 1. Nvidia 驱动源...”为内容创建页面 wikitext text/x-wiki = openSUSE Tumbleweed NVidia 闭源驱动安装使用指南 = 适用linux版本:4.5.0 适用nvidia驱动版本:361.42 == 文件位置 == 1. Nvidia 驱动源文件位置: /usr/src/nvidia-361.42/ 2. Nvidia 内核模块驱动位置:/lib/modules/4.5.0-3-default/kernel/drivers/video/nvidia.ko, nvidia-uvm.ko, nvidia-modeset.ko 3. Nvidia Xorg驱动位置:/usr/lib64/xorg/modules/extensions/libglx.so.361.42 == 注意事项 == 更新kernel或者更新xorg-server均有可能导致nvidia模块被覆盖。 对于kernel,需要重新depmod -a并且mkinitrd 对于xorg-server,需要保证/usr/lib64/xorg/modules/extensions/libglx.so链接指向nvidia的libglx文件libglx.so.361.42。 == 目前状态 == 锁死kernel,xorg-server和nvidia驱动版本,待大版本更新后再调试。 - 2016年4月 ad911dc6559dca0f25398d25b2d70ab86b028779 Ugly things 0 146 526 2016-04-29T16:56:18Z HenryHu 1 以“== 看了也看不懂的错误消息 == === 编译器错误消息 === === Scala/Spark 错误消息 === == 改也改不了的密码 == === Google 密码 === 改...”为内容创建页面 wikitext text/x-wiki == 看了也看不懂的错误消息 == === 编译器错误消息 === === Scala/Spark 错误消息 === == 改也改不了的密码 == === Google 密码 === 改密码之后,所有Session会被终止。 6ac4065a955843635dbcab0d8a7af97b770e7d8d Cheatsheet 0 147 527 2016-05-13T21:05:56Z HenryHu 1 以“== Disk rescue == dd if=/dev/sdx of=deadhd.bin conv=noerror,sync * noerror: continue if error occurred * sync: sync the input/output position, so errors are re...”为内容创建页面 wikitext text/x-wiki == Disk rescue == dd if=/dev/sdx of=deadhd.bin conv=noerror,sync * noerror: continue if error occurred * sync: sync the input/output position, so errors are replaced with 0s fcb71ca2a0d482a1ab71ff03ab315d3acb92a3bd DPI 0 148 528 2016-05-17T01:09:14Z HenryHu 1 以“{| class=wikitable |- ! Resolution ! Size ! DPI |- | 1080p | 15' | 146.9 |- | 1080p | 22' | 100.1 |- | 1080p | 27' | 81.6 |- | 1080p | 34' | 64.8 |- | 2160p | 30' | ...”为内容创建页面 wikitext text/x-wiki {| class=wikitable |- ! Resolution ! Size ! DPI |- | 1080p | 15' | 146.9 |- | 1080p | 22' | 100.1 |- | 1080p | 27' | 81.6 |- | 1080p | 34' | 64.8 |- | 2160p | 30' | 146.9 |} a914e271da290a3d7edb3920f1bfa7abe4314a70 Linux compatibility 0 149 529 2016-06-17T03:18:44Z HenryHu 1 以“== Softwares using Linux compatibility == === Flash player === * Alternative: pipelight Mostly works, although sometimes it would crash === Skype === * Alternative:...”为内容创建页面 wikitext text/x-wiki == Softwares using Linux compatibility == === Flash player === * Alternative: pipelight Mostly works, although sometimes it would crash === Skype === * Alternative: mobile version All the recent calls are made on mobile devices * Alternative: QQ QQ video seems to be stabler === Android SDK === fastboot and adb have native versions. But the emulator is still non-native. 05264d3a1520778920591340dc7553392b776f58 Docker Cheatsheet 0 150 530 2016-06-29T21:43:06Z HenryHu 1 以“== Concepts == * Container ID: a long hex string. Usually its prefix is enough. * Image: a template. == Basic usage == === Get software image === docker pull <n...”为内容创建页面 wikitext text/x-wiki == Concepts == * Container ID: a long hex string. Usually its prefix is enough. * Image: a template. == Basic usage == === Get software image === docker pull <name>:<version> === Run === docker run -t -i <image name> === Attach === docker attach -a -i <container ID> === Mount external directory === docker run -t -i -v <host directory>:<guest directory> <image name> == Management == === List containers === docker ps -a Only the running ones: docker ps === Remove container === docker rm <container ID> === Get history console output === docker logs <container ID> === Create template from current container === docker commit <container ID> <new image name> c752d5037e059be75e5bf1f510cc3942d9e96c63 531 530 2016-06-29T21:43:30Z HenryHu 1 /* Get software image */ wikitext text/x-wiki == Concepts == * Container ID: a long hex string. Usually its prefix is enough. * Image: a template. == Basic usage == === Get software image === docker pull <name>[:<version>] === Run === docker run -t -i <image name> === Attach === docker attach -a -i <container ID> === Mount external directory === docker run -t -i -v <host directory>:<guest directory> <image name> == Management == === List containers === docker ps -a Only the running ones: docker ps === Remove container === docker rm <container ID> === Get history console output === docker logs <container ID> === Create template from current container === docker commit <container ID> <new image name> 5439308b7afc9cd89b6014f5d8b99ba354fabf59 532 531 2016-06-29T21:44:20Z HenryHu 1 /* Concepts */ wikitext text/x-wiki == Concepts == * Container ID: a long hex string. Usually its prefix is enough. * Image: a template. == Common images == * ubuntu: Ubuntu distribution * debian: Debian distribution * busybox: basic Busybox == Basic usage == === Get software image === docker pull <name>[:<version>] === Run === docker run -t -i <image name> === Attach === docker attach -a -i <container ID> === Mount external directory === docker run -t -i -v <host directory>:<guest directory> <image name> == Management == === List containers === docker ps -a Only the running ones: docker ps === Remove container === docker rm <container ID> === Get history console output === docker logs <container ID> === Create template from current container === docker commit <container ID> <new image name> b1924ef59ed4603a988358b2f9e9a81dcaf0d0ad 533 532 2016-06-29T21:44:44Z HenryHu 1 /* Management */ wikitext text/x-wiki == Concepts == * Container ID: a long hex string. Usually its prefix is enough. * Image: a template. == Common images == * ubuntu: Ubuntu distribution * debian: Debian distribution * busybox: basic Busybox == Basic usage == === Get software image === docker pull <name>[:<version>] === Run === docker run -t -i <image name> === Attach === docker attach -a -i <container ID> === Mount external directory === docker run -t -i -v <host directory>:<guest directory> <image name> == Management == === List containers === docker ps -a Only the running ones: docker ps === Remove container === docker rm <container ID> === Get history console output === docker logs <container ID> === Create template from current container === docker commit <container ID> <new image name> === List images === docker images f52317e0798f76119e45bd9320b77131863da5a8 534 533 2016-06-29T22:25:49Z HenryHu 1 /* Run */ wikitext text/x-wiki == Concepts == * Container ID: a long hex string. Usually its prefix is enough. * Image: a template. == Common images == * ubuntu: Ubuntu distribution * debian: Debian distribution * busybox: basic Busybox == Basic usage == === Get software image === docker pull <name>[:<version>] === Run === docker run -it <image name> === Attach === docker attach -a -i <container ID> === Mount external directory === docker run -t -i -v <host directory>:<guest directory> <image name> == Management == === List containers === docker ps -a Only the running ones: docker ps === Remove container === docker rm <container ID> === Get history console output === docker logs <container ID> === Create template from current container === docker commit <container ID> <new image name> === List images === docker images 99115e622eb8f4b4a0164c55dfd5bd4a3fcf9d79 535 534 2016-06-29T22:26:00Z HenryHu 1 /* Attach */ wikitext text/x-wiki == Concepts == * Container ID: a long hex string. Usually its prefix is enough. * Image: a template. == Common images == * ubuntu: Ubuntu distribution * debian: Debian distribution * busybox: basic Busybox == Basic usage == === Get software image === docker pull <name>[:<version>] === Run === docker run -it <image name> === Attach === docker attach -ai <container ID> === Mount external directory === docker run -t -i -v <host directory>:<guest directory> <image name> == Management == === List containers === docker ps -a Only the running ones: docker ps === Remove container === docker rm <container ID> === Get history console output === docker logs <container ID> === Create template from current container === docker commit <container ID> <new image name> === List images === docker images 04a5b78295171f69f509f1ce4e43751c1900254a 536 535 2016-06-29T22:28:22Z HenryHu 1 /* Mount external directory */ wikitext text/x-wiki == Concepts == * Container ID: a long hex string. Usually its prefix is enough. * Image: a template. == Common images == * ubuntu: Ubuntu distribution * debian: Debian distribution * busybox: basic Busybox == Basic usage == === Get software image === docker pull <name>[:<version>] === Run === docker run -it <image name> === Attach === docker attach -ai <container ID> === Mount external directory === docker run -it -v <host directory>:<guest directory> <image name> == Management == === List containers === docker ps -a Only the running ones: docker ps === Remove container === docker rm <container ID> === Get history console output === docker logs <container ID> === Create template from current container === docker commit <container ID> <new image name> === List images === docker images 68ba38b28f079f8c6772892576056a1b99c1aecc 537 536 2016-06-29T22:28:47Z HenryHu 1 /* Common images */ wikitext text/x-wiki == Concepts == * Container ID: a long hex string. Usually its prefix is enough. * Image: a template. == Common images == * ubuntu: Ubuntu distribution * debian: Debian distribution * busybox: basic Busybox * gcc: with GCC ** gcc:5: gcc version 5 == Basic usage == === Get software image === docker pull <name>[:<version>] === Run === docker run -it <image name> === Attach === docker attach -ai <container ID> === Mount external directory === docker run -it -v <host directory>:<guest directory> <image name> == Management == === List containers === docker ps -a Only the running ones: docker ps === Remove container === docker rm <container ID> === Get history console output === docker logs <container ID> === Create template from current container === docker commit <container ID> <new image name> === List images === docker images c4f2eb9092d435a6a9d17722b91eaaf23890093b 538 537 2016-07-01T22:28:59Z HenryHu 1 /* Attach */ wikitext text/x-wiki == Concepts == * Container ID: a long hex string. Usually its prefix is enough. * Image: a template. == Common images == * ubuntu: Ubuntu distribution * debian: Debian distribution * busybox: basic Busybox * gcc: with GCC ** gcc:5: gcc version 5 == Basic usage == === Get software image === docker pull <name>[:<version>] === Run === docker run -it <image name> === Attach === Attach to a running instance docker attach <container ID> === Mount external directory === docker run -it -v <host directory>:<guest directory> <image name> == Management == === List containers === docker ps -a Only the running ones: docker ps === Remove container === docker rm <container ID> === Get history console output === docker logs <container ID> === Create template from current container === docker commit <container ID> <new image name> === List images === docker images 14d06b3e6c0655976eeda31293a4a6266e36228f 539 538 2016-07-01T22:29:35Z HenryHu 1 /* Run */ wikitext text/x-wiki == Concepts == * Container ID: a long hex string. Usually its prefix is enough. * Image: a template. == Common images == * ubuntu: Ubuntu distribution * debian: Debian distribution * busybox: basic Busybox * gcc: with GCC ** gcc:5: gcc version 5 == Basic usage == === Get software image === docker pull <name>[:<version>] === Run === docker run -it <image name> === Start === Start a stopped instance docker start -ai <container ID> === Attach === Attach to a running instance docker attach <container ID> === Mount external directory === docker run -it -v <host directory>:<guest directory> <image name> == Management == === List containers === docker ps -a Only the running ones: docker ps === Remove container === docker rm <container ID> === Get history console output === docker logs <container ID> === Create template from current container === docker commit <container ID> <new image name> === List images === docker images f8531faefadeee00d528210c510b78ebc1d9fd2d Surface Pro 4 0 151 540 2016-09-03T17:01:59Z HenryHu 1 以“== FreeBSD == 至少比Surface 3的情况好 * 靠UEFI正常启动。 * 硬盘是PCIe上面的NVMe,能够认出来。 * 看上去音频能够工作。 * USB无...”为内容创建页面 wikitext text/x-wiki == FreeBSD == 至少比Surface 3的情况好 * 靠UEFI正常启动。 * 硬盘是PCIe上面的NVMe,能够认出来。 * 看上去音频能够工作。 * USB无法初始化。错误是当reattach_port的时候timeout。 d93c358e9f0b03b0f3f86567e4c18baf507a6382 542 540 2016-10-15T03:50:30Z HenryHu 1 wikitext text/x-wiki == FreeBSD == 至少比Surface 3的情况好 * 靠UEFI正常启动。 * 硬盘是PCIe上面的NVMe,能够认出来。 * 看上去音频能够工作。 * USB无法初始化。错误是当reattach_port的时候timeout。 == Bugs == === 卡死在login屏幕 === * 发生于:login屏幕 不断转圈,进不去。 只要降低UAC级别到不黑屏就可以 === 触摸屏失效 === * 发生于:突然就出现,没啥规律 * 频率:低 触摸屏突然没反应了。 hibernate再回来。 === 键盘/触摸板失效 === * 发生于:任何时候 * 频率:非常低 触摸板/键盘失效,没反应。 卸掉键盘再装回来。 === Wifi中断 === * 发生于:任何时候 * 频率:一天一次? Wifi突然无法使用,过一会系统自己检测到问题reset网卡就好了。 没啥办法,等他自己好。 === Explorer卡死 === * 发生于:任何时候 * 频率:一天数次? Explorer卡死,点了没反应,时间也不变。 杀掉Explorer重开。 === ChsIME暴走 === * 发生于:从待机恢复后/启动后 * 频率:挺常见的 ChsIME开始持续占用30%的CPU。 禁止System启动它的权限。干掉进程会好一段时间。 === 窗口大小异常 === * 发生于:切换外置屏幕/切换回来 * 频率:一定会 某些窗口(输入法/IE/其他老程序)会特别大/特别小。 注销一次再进来。 7d96b7d709506c77acfc16a849433aa649666b2a DiezelSun 0 152 541 2016-09-19T18:20:18Z Sesma8 26 以“'''Diezel Sun''' - 藝術家,3D建模,視覺藝術新方向的創始人。該藝術家的主題是在世界上很受歡迎。這個話題與宗教,空間,古...”为内容创建页面 wikitext text/x-wiki '''Diezel Sun''' - 藝術家,3D建模,視覺藝術新方向的創始人。該藝術家的主題是在世界上很受歡迎。這個話題與宗教,空間,古代經文有關。 ==參考== *[http://en.wiki.unrealsoftware.de/index.php/DiezelSun_3d_graphics - 虛幻引擎] f252ea04539796f9f6cee7145fa909a4367bf91d Vim startup 0 153 543 2016-10-27T19:55:55Z HenryHu 1 以“== Vim Startup Speed == === General === * YouCompleteMe: 200ms * tagbar: 175ms === Python files === * pymode_folding: 200ms * pymode_lint: 177ms Even without linte...”为内容创建页面 wikitext text/x-wiki == Vim Startup Speed == === General === * YouCompleteMe: 200ms * tagbar: 175ms === Python files === * pymode_folding: 200ms * pymode_lint: 177ms Even without linter present! 0822705058838e0064c01cda747280a7f0bc0fb5 VBScript Cheatsheet 0 154 544 2016-11-01T16:51:27Z HenryHu 1 以“== VBScript == <source lang="vb"> set wshShell = CreateObject("WScript.Shell") </source> === Sub/Function === <source lang="vb"> Sub foo(arg1, arg2) ... End Sub fo...”为内容创建页面 wikitext text/x-wiki == VBScript == <source lang="vb"> set wshShell = CreateObject("WScript.Shell") </source> === Sub/Function === <source lang="vb"> Sub foo(arg1, arg2) ... End Sub foo 1, 2 Function bar(arg1, arg2) ... bar = retVal End Function ret = bar(3, 4) </source> === Start process (hidden) === <source lang="vb"> wshShell.Run """Hello.exe"" world", 0 </source> === Check if started === From stackoverflow <source lang="vb"> sComputerName = "." Set objWMIService = GetObject("winmgmts:\\" & sComputerName & "\root\cimv2") sQuery = "SELECT * FROM Win32_Process WHERE Name LIKE '%" + procName + "%'" Set objItems = objWMIService.ExecQuery(sQuery) 'iterate all item(s) For Each objItem In objItems started = true Next </source> e60a611a40538e3614497db24aad76daf4217e3c Bot User Agents 0 155 545 2016-12-01T21:03:20Z HenryHu 1 以“<pre> > tail -n 1000000 nginx-access.log | egrep -o 'compatible; .*;' | cut -d \; -f 2-2 | sort | uniq -c | sort -h 1 discobot/1.0 1 Feedspotbot/1.0 1 Ko...”为内容创建页面 wikitext text/x-wiki <pre> > tail -n 1000000 nginx-access.log | egrep -o 'compatible; .*;' | cut -d \; -f 2-2 | sort | uniq -c | sort -h 1 discobot/1.0 1 Feedspotbot/1.0 1 Konqueror/3.0-rc2 1 Konqueror/3.1-rc2 1 Konqueror/3.1-rc4 1 Konqueror/3.1-rc5 1 Konqueror/3.1-rc6 1 Konqueror/3.5 1 MSIE 5.0 1 MSIE 5.5 1 MSIE 8.0, windows NT 5.1 1 OmniWeb/4.1-v422 1 OptimizationCrawler/0.2 1 Uptimebot/0.2.41 1 WebCapture 1.0 1 WebCapture 2.0 1 Yahoo! Slurp China 1 YodaoBot/1.0 2 DomainSigmaCrawler/0.1 2 MegaIndex.ru/2.0 2 MSIE 10.6 2 Qwantify/2.2w 2 Uptimebot/0.2.43 4 Let's Encrypt validation server 4 MixrankBot 4 Twingly Recon 5 MSIE8.0 5 Qwantify/2.3w 8 FlipboardRSS/1.2 11 archive.org_bot 12 DuckDuckGo-Favicons-Bot/1.0 13 Gluten Free Crawler/1.0 13 MSIE 5.01 14 YandexImages/3.0 15 spbot/5.0.3 18 MSIE 9.11 18 spbot/5.0.2 21 Uptimebot/1.0 22 NetcraftSurveyAgent/1.0 31 WBSearchBot/1.1 36 SeznamBot/3.2 38 Nmap Scripting Engine 48 DotBot/1.1 50 Dataprovider/6.101 77 MSIE or Firefox mutant 79 MojeekBot/0.6 85 theoldreader.com 120 SMTBot/1.0 154 FlipboardRSS/1.1 173 Exabot/3.0 196 Googlebot-Mobile/2.1 216 Linux x86_64 311 linkdexbot/2.0 361 MSIE 10.0 447 MSIE 7.0 481 aiHitBot/2.9 502 SiteExplorer/1.1b 750 MSIE 7.0 767 MJ12bot/v1.4.7 787 MJ12bot/v1.4.6 835 Windows 861 MSIE 8.0 981 MSIE 6.0 1215 YandexMobileBot/3.0 1953 SiteExplorer/1.0b 2518 HaosouSpider 2579 Yahoo! Slurp 3017 YandexBot/3.0 6761 MSIE 9.0 8005 BLEXBot/1.0 9124 Baiduspider/2.0 12091 bingbot/2.0 23582 Googlebot/2.1 35585 MJ12bot/v1.4.5 88015 AhrefsBot/5.1 89224 XoviBot/2.0 255831 SemrushBot/1.1~bl </pre> So, SemrushBot, XoviBot and AhrefsBot are banned. ebc22ee984dedf8efe1d3054faab41393bbe5bd7 SubsConscious 0 3 546 436 2016-12-01T23:05:25Z HenryHu 1 wikitext text/x-wiki SubsConscious 是哥大边上,Amsterdam Av. 上的一个店,主营subs和salad SubsConscious: great food. great service. www.subsconscious.com == 关键词 == 材料: * Turkey * Beef * Chicken Cutlet 炸鸡块 配料:Onion Cheese: Sauce: == 评价 == * graduate 过来之后吃的第一种,挺好吃的,郭总推荐,郭总基本上只吃这个…… * lecture 本来我觉得是各种里面最好的,但是有一次有一个很不好吃。不过那个好像是拿错了,因为里面有炸鱼…… 补充:那个的确拿错了,后来又吃了一次,的确很好吃 * ivy-league 好像不是很好吃…… * double-trouble 挺好吃的 * bar exam Jingyue推荐的,有beef,味道不错 * bronx-10461 刚开始吃感觉不错,不过吃到后来有奇怪的味道。貌似有汉堡里面那种蔬菜。 * twice-as-nice 挺不好吃的…… * valedictorian 不错,turkey系列之一,不过名字不好读 * iq 这就是上次lecture拿错的那个!不太好吃 * gpa 这个里面也有鱼,不过好像味道稍微好一些…… 等等,这个绿色的粘稠液体是啥…… 大概是蔬菜酱…… 幸好不是芥末…… 这个酱吃起来太恶心了…… 以后不要了…… * life-guard 终于凑满了10个,吃了个life guard 和graduate很像…… 不错 * triple-play 嗯,味道挺淡的。和lecture有点像,不过有好多青椒和生菜。一般。 * lions-den 非常好吃 * al's-advantage 比lions-den更好吃,基本上是最高水平 今儿又吃了一次,的确不错,没有任何缺陷 其实挺像汉堡的味道…… ef253c104dd42916d19d431069cde615c9b8a523 MediaWiki:Sidebar 8 12 547 32 2016-12-01T23:28:31Z HenryHu 1 wikitext text/x-wiki * navigation ** mainpage|mainpage-description ** recentchanges-url|recentchanges ** randompage-url|randompage ** helppage|help ** http://www.henryhu.net|Henry's Home * SEARCH * TOOLBOX * LANGUAGES 6df9afcc850d3b3cc18d8f6e4a6bf902d8880c6c 用户:HenryHu 2 156 548 2016-12-01T23:29:48Z HenryHu 1 创建空白页面 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 555 548 2016-12-01T23:40:56Z HenryHu 1 wikitext text/x-wiki Hello, I'm Henry Hu. == Public accounts == * [//twitter.com/henryhu @henryhu] Twitter account == Websites == * [//www.henryhu.net Henry's Home] My home page 7848ef0c0eb0720185c1b584ba2bd78cc7e27c00 用户讨论:HenryHu 3 157 549 2016-12-01T23:30:00Z HenryHu 1 创建空白页面 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 MediaWiki:Tagline 8 158 550 2016-12-01T23:32:29Z HenryHu 1 创建页面,内容为“My public wiki” wikitext text/x-wiki My public wiki ee03d9b788e2b205ed320a22ce04846fbc1f5881 559 550 2016-12-01T23:48:07Z HenryHu 1 wikitext text/x-wiki My public wiki 所以这页到底是干啥的…… e892fd993857324b96265bd88278fb5967feff49 MediaWiki:Sitesubtitle 8 159 551 2016-12-01T23:33:08Z HenryHu 1 创建页面,内容为“Yet another wiki” wikitext text/x-wiki Yet another wiki d1fb9e0d7a93b0179b1c4ee4a0f2b76982a2dec1 552 551 2016-12-01T23:33:19Z HenryHu 1 wikitext text/x-wiki My public notebook 398110d52fcb145998a0f2261320a6f36b5e6cd0 556 552 2016-12-01T23:45:35Z HenryHu 1 wikitext text/x-wiki Many strange things b4241f2c2a3c7b0b5a595f26fa9af24f741ee656 HenryNotebook:隐私政策 4 160 553 2016-12-01T23:34:45Z HenryHu 1 创建页面,内容为“Privacy? Don't leak private information on this site, that's all.” wikitext text/x-wiki Privacy? Don't leak private information on this site, that's all. 08ca2125518c9bfebe96fd1bb6bb21a72b318c76 557 553 2016-12-01T23:46:51Z HenryHu 1 wikitext text/x-wiki Privacy? Don't leak private information on this site, that's all. 隐私?都写到公开Wiki上了还有啥隐私…… ee11659b39fc911e3c99b14f23b817e7bba782fd 558 557 2016-12-01T23:46:59Z HenryHu 1 wikitext text/x-wiki Privacy? Don't leak private information on this site, that's all. 隐私?都写到公开Wiki上了还有啥隐私…… 38a83f2bb448be7d61a88b958f2dfbb7c4853759 HenryNotebook:关于 4 161 554 2016-12-01T23:35:54Z HenryHu 1 创建页面,内容为“Henry Hu的公开Wiki,如果你也想参与编辑可以自己建账号。欢迎其他人使用本Wiki……” wikitext text/x-wiki Henry Hu的公开Wiki,如果你也想参与编辑可以自己建账号。欢迎其他人使用本Wiki…… cbd47e17ff641551b2b7871ba75d3589ba03bf21 模板:Optional 10 162 560 2017-01-05T22:06:59Z HenryHu 1 创建页面,内容为“<noinclude>{| class="wikitable" |- |</noinclude>style="background:#ffffe0; color:black; vertical-align: middle; text-align: {{{align|center}}}; {{{style|}}}" class="...” wikitext text/x-wiki <noinclude>{| class="wikitable" |- |</noinclude>style="background:#ffffe0; color:black; vertical-align: middle; text-align: {{{align|center}}}; {{{style|}}}" class="table-no" | {{{1|No}}}<noinclude> |} {{documentation}} </noinclude> 76f02e71a78db1749910ce4eac42e334b26e144f 561 560 2017-01-05T22:14:02Z HenryHu 1 wikitext text/x-wiki <noinclude>{| class="wikitable" |- |</noinclude>style="background:#ffffe0; color:black; vertical-align: middle; text-align: {{{align|center}}}; {{{style|}}}" class="table-opt" | {{{1|Opt}}}<noinclude> |} {{documentation}} </noinclude> ed7a784b2214c5c6d3b6c4f25baa80dfe0beb853 Messaging App 0 163 562 2017-01-05T22:33:22Z HenryHu 1 创建页面,内容为“Chrome App不算Desktop Client。 Facebook Messenger用的是MQTT协议,居然还是ISO标准…… QQ For Linux这种古董还是算了…… {| class="wikitable...” wikitext text/x-wiki Chrome App不算Desktop Client。 Facebook Messenger用的是MQTT协议,居然还是ISO标准…… QQ For Linux这种古董还是算了…… {| class="wikitable sortable" |- ! App !! Open Proto.!! Web !!Windows!! *nix !! Open Source !! Mobile!!Encrypted!! Distributed !! Group |- | Google Hangouts || {{No}} ||{{Yes}}||{{No}} || {{No}}|| {{No}} ||{{Yes}}||{{No}} || {{No}} ||{{Yes}} |- | Telegram || {{Yes}} ||{{Yes}}||{{Yes}}||{{Yes}}|| {{Yes}} ||{{Yes}}||{{Optional}}|| {{No}} ||{{Yes}} |- | Signal || {{Yes}} ||{{No}} || {{No}}||{{No}} || {{Yes}} ||{{Yes}}||{{Yes}} || {{No}} ||{{Yes}} |- | WhatsApp || 示例 ||{{Yes}}|| 示例 || 示例 || 示例 ||{{Yes}}|| 示例 || {{No}} || 示例 |- | Facebook Messenger|| {{Yes}} ||{{Yes}}||{{Yes}}|| 示例 || 示例 ||{{Yes}}|| 示例 || {{No}} || 示例 |- | iMessage || {{No}} ||{{No}} ||{{No}} ||{{No}} || {{No}} ||{{No}} || 示例 || {{No}} || 示例 |- | QQ || {{No}} ||{{Yes}}||{{Yes}}||{{No}} || {{No}} ||{{Yes}}|| || {{No}} ||{{Yes}} |- | WeChat || {{No}} ||{{Yes}}||{{Yes}}||{{No}} || {{No}} ||{{Yes}}|| || {{No}} ||{{Yes}} |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |} c4bc28854542cdc1af37be8f9a15c73bb2b5e61a 563 562 2017-01-05T23:09:48Z HenryHu 1 wikitext text/x-wiki Chrome App不算Desktop Client。 Facebook Messenger用的是MQTT协议,居然还是ISO标准…… QQ For Linux 这种古董还是算了…… Encrypted 指 End-to-End Encrypted {| class="wikitable sortable" |- ! App !! Open Proto.!! Web !!Windows!! *nix !! Open Source !!Android!!Encrypted!! Distributed !! Group |- | Google Hangouts || {{No}} ||{{Yes}}||{{No}} || {{No}}|| {{No}} ||{{Yes}}||{{No}} || {{No}} ||{{Yes}} |- | Telegram || {{Yes}} ||{{Yes}}||{{Yes}}||{{Yes}}|| {{Yes}} ||{{Yes}}||{{Optional}}|| {{No}} ||{{Yes}} |- | Signal || {{Yes}} ||{{No}} || {{No}}||{{No}} || {{Yes}} ||{{Yes}}||{{Yes}} || {{No}} ||{{Yes}} |- | WhatsApp || {{Yes}} ||{{Yes}}||{{Yes}}|| || {{No}} ||{{Yes}}|| {{Yes}} || {{No}} ||{{Yes}} |- | Facebook Messenger|| {{Yes}} ||{{Yes}}||{{Yes}}|| || {{No}} ||{{Yes}}||{{Optional}}|| {{No}} ||{{Yes}} |- | iMessage || {{No}} ||{{No}} ||{{No}} ||{{No}} || {{No}} ||{{No}} || {{Yes}} || {{No}} ||{{Yes}} |- | QQ || {{No}} ||{{Yes}}||{{Yes}}||{{No}} || {{No}} ||{{Yes}}||{{No}} || {{No}} ||{{Yes}} |- | WeChat || {{No}} ||{{Yes}}||{{Yes}}||{{No}} || {{No}} ||{{Yes}}||{{No}} || {{No}} ||{{Yes}} |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |} fb69e13b6f793e90e5b4b78f6368bc2983aa645d 564 563 2017-01-05T23:18:19Z HenryHu 1 wikitext text/x-wiki Chrome App不算Desktop Client。 Facebook Messenger用的是MQTT协议,居然还是ISO标准…… QQ For Linux 这种古董还是算了…… Encrypted 指 End-to-End Encrypted。 Skype for Linux? 呵呵呵…… {| class="wikitable sortable" |- ! App !! Open Proto.!! Web !!Windows!! *nix !! Open Source !!Android!!Encrypted!! Distributed !! Group |- | Google Hangouts || {{No}} ||{{Yes}}||{{No}} || {{No}}|| {{No}} ||{{Yes}}||{{No}} || {{No}} ||{{Yes}} |- | Telegram || {{Yes}} ||{{Yes}}||{{Yes}}||{{Yes}}|| {{Yes}} ||{{Yes}}||{{Optional}}|| {{No}} ||{{Yes}} |- | Signal || {{Yes}} ||{{No}} || {{No}}||{{No}} || {{Yes}} ||{{Yes}}||{{Yes}} || {{No}} ||{{Yes}} |- | WhatsApp || {{Yes}} ||{{Yes}}||{{Yes}}|| || {{No}} ||{{Yes}}|| {{Yes}} || {{No}} ||{{Yes}} |- | Facebook Messenger|| {{Yes}} ||{{Yes}}||{{Yes}}|| || {{No}} ||{{Yes}}||{{Optional}}|| {{No}} ||{{Yes}} |- | iMessage || {{No}} ||{{No}} ||{{No}} ||{{No}} || {{No}} ||{{No}} || {{Yes}} || {{No}} ||{{Yes}} |- | QQ || {{No}} ||{{Yes}}||{{Yes}}||{{No}} || {{No}} ||{{Yes}}||{{No}} || {{No}} ||{{Yes}} |- | WeChat || {{No}} ||{{Yes}}||{{Yes}}||{{No}} || {{No}} ||{{Yes}}||{{No}} || {{No}} ||{{Yes}} |- | Skype || {{No}} ||{{Yes}}||{{Yes}}||{{No}} || {{No}} ||{{Yes}}||{{No}} || {{No}} ||{{Yes}} |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |} 68adf7db6fc9b3e1f4e3ee0d3d0056bbf22276bb Streaming Music 0 164 565 2017-01-11T20:11:19Z HenryHu 1 创建页面,内容为“{| class="wikitable sortable" |- ! Service !! Price !! Web !! Windows !! *nix !! Mobile !! Quality !! Speed !! Lyrics !! Song Availability !! Abroad Availability...” wikitext text/x-wiki {| class="wikitable sortable" |- ! Service !! Price !! Web !! Windows !! *nix !! Mobile !! Quality !! Speed !! Lyrics !! Song Availability !! Abroad Availability !! 标题文字 |- | Google Music|| $10/month, Free for radio / upload || {{Optional|HTML5 (DRM) or Flash}} || {{Optional|3rd-party}} || {{Optional|3rd-party}} || {{Yes}}|| as-is || {{Yes|Good}} || {{No}} || {{Optional|Low, can upload}} || {{Yes}} || 示例 |- | Netease Music || 8 RMB/month, 88 RMB/year, low-quality preview || {{Yes|HTML5}} || {{Yes}} || {{Optional|3rd-party}} || {{Yes}} || {{Yes|Good, lossless?}} || {{Optional|Poor}} || {{Yes}} || {{No|Many marked as unavailable}} || {{Optional|OK when paid}} || 示例 |- | Xiami || 10 RMB/month, 98 RMB/year, very low-quality preview || {{Optional|Flash}} || {{Yes}} || {{Optional|3rd-party}} || {{Yes}} || {{Yes|320Kbps?}} || {{Optional|Poor}} || {{Yes}} || {{No|Many marked as unavailable}} || {{Optional|OK when paid}} || 示例 |- | Apple Music || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |- | QQ Music || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |- | Spotify || 5$/month || {{Optional|Flash}} || {{Yes}} || {{Optional|Abandoned}} || {{Yes}} || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |} c71fd959fcefa031cf127cb7cb00b4c384567536 Streaming Music 0 164 566 565 2017-01-11T20:24:56Z HenryHu 1 wikitext text/x-wiki {| class="wikitable sortable" |- ! Service !! Price !! Web !! Windows !! *nix !! Mobile !! Quality !! Speed !! Lyrics !! Song Availability !! Abroad Availability !! Limit |- | Google Music || $10/m, free for radio || {{Optional|HTML5 (DRM) or Flash}} || {{Optional|3rd-party}} || {{Optional|3rd-party}} || {{Yes}}|| {{Yes|Good}} || {{Yes|Good}} || {{No}} || {{No|Low}} || {{Yes}} || 示例 |- | Google Music Library || {{Yes|Free}} || {{Optional|HTML5 (DRM) or Flash}} || {{Optional|3rd-party}} || {{Optional|3rd-party}} || {{Yes}}|| {{Yes|as-is}} || {{Yes|Good}} || {{No}} || {{Optional|as-is}} || {{Yes}} || 20000 total |- | Netease Music || 8¥/m, 88¥/y, low-quality preview || {{Yes|HTML5}} || {{Yes}} || {{Optional|3rd-party}} || {{Yes}} || {{Yes|Good, lossless?}} || {{Optional|Poor}} || {{Yes}} || {{Optional|Many marked as unavailable}} || {{Optional|OK when paid}} || 300 down/m |- | Xiami || 10¥/m, 98¥/y, very low-quality preview || {{Optional|Flash}} || {{Yes}} || {{Optional|3rd-party}} || {{Yes}} || {{Yes|320Kbps?}} || {{Optional|Poor}} || {{Yes}} || {{Optional|Many marked as unavailable}} || {{Optional|OK when paid}} || 100 down/m |- | Apple Music || 示例 || 示例 || 示例 || 示例 || {{Yes}} || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |- | QQ Music || 示例 || 示例 || 示例 || 示例 || {{Yes}} || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |- | Spotify || 5$/month || {{Optional|Flash}} || {{Yes}} || {{Optional|Abandoned}} || {{Yes}} || 示例 || 示例 || 示例 || {{No|Low}} || {{Yes}} || 示例 |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |} bc5503d5c1ddec791a83c71006cc1592314330bd 首页 0 1 567 481 2017-01-11T20:29:27Z HenryHu 1 wikitext text/x-wiki [[SubsConscious]] [[:Category:脚本|Scripts]] [[Package Management]] [[Startup Management]] [[Git Cheatsheet]] [[BBS Project]] [[openSUSE]] [[Messaging App]] [[Streaming Music]] <!-- == 入门 == * [http://www.mediawiki.org/wiki/Manual:Configuration_settings MediaWiki 配置设置列表] * [http://www.mediawiki.org/wiki/Manual:FAQ/zh-hans MediaWiki常见问题] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki发布邮件列表] --> bf0d696ef00aecf7887897ba9b49d521837603f3 593 567 2020-11-14T05:49:36Z HenryHu 1 wikitext text/x-wiki [[SubsConscious]] [[:Category:脚本|Scripts]] [[Package Management]] [[Startup Management]] [[Git Cheatsheet]] [[BBS Project]] [[openSUSE]] [[Messaging App]] [[Streaming Music]] [[My Stuff]] <!-- == 入门 == * [http://www.mediawiki.org/wiki/Manual:Configuration_settings MediaWiki 配置设置列表] * [http://www.mediawiki.org/wiki/Manual:FAQ/zh-hans MediaWiki常见问题] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki发布邮件列表] --> 08c1b4e9dc8846e97f8946ba7fd37c621a8edaf2 596 593 2022-04-09T01:24:56Z HenryHu 1 wikitext text/x-wiki [[SubsConscious]] [[:Category:脚本|Scripts]] [[Package Management]] [[Startup Management]] [[Git Cheatsheet]] [[BBS Project]] [[openSUSE]] [[Messaging App]] [[Streaming Music]] [[My Stuff]] [[Messenger Bags]] <!-- == 入门 == * [http://www.mediawiki.org/wiki/Manual:Configuration_settings MediaWiki 配置设置列表] * [http://www.mediawiki.org/wiki/Manual:FAQ/zh-hans MediaWiki常见问题] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki发布邮件列表] --> 6b09843205bcd32d2026fccb4f7e2392f034e778 602 596 2023-06-25T19:29:10Z HenryHu 1 wikitext text/x-wiki [[SubsConscious]] [[:Category:脚本|Scripts]] [[Package Management]] [[Startup Management]] [[Git Cheatsheet]] [[BBS Project]] [[openSUSE]] [[Messaging App]] [[Streaming Music]] [[My Stuff]] [[Messenger Bags]] [[Shenzhen I/O]] <!-- == 入门 == * [http://www.mediawiki.org/wiki/Manual:Configuration_settings MediaWiki 配置设置列表] * [http://www.mediawiki.org/wiki/Manual:FAQ/zh-hans MediaWiki常见问题] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki发布邮件列表] --> 87cf76a9c6ac7239d9ccc3b15d7c30a5aefb7274 605 602 2023-07-16T21:08:02Z HenryHu 1 wikitext text/x-wiki [[SubsConscious]] [[:Category:脚本|Scripts]] [[Package Management]] [[Startup Management]] [[Git Cheatsheet]] [[BBS Project]] [[openSUSE]] [[Messaging App]] [[Streaming Music]] [[My Stuff]] [[Messenger Bags]] [[Shenzhen I/O]] [[Home Improvement Plan]] 06b14880596f5a3d45d77b8dd12bfb1da257243e 607 605 2023-07-23T03:07:19Z HenryHu 1 wikitext text/x-wiki [[SubsConscious]] [[:Category:脚本|Scripts]] [[Package Management]] [[Startup Management]] [[Git Cheatsheet]] [[BBS Project]] [[openSUSE]] [[Messaging App]] [[Streaming Music]] [[My Stuff]] [[Messenger Bags]] [[Shenzhen I/O]] [[Home Improvement Plan]] [[Restaurants]] 82e23f0033f95d9f22d6c67592095879162f17a5 Messaging App 0 163 568 564 2017-01-12T19:31:45Z HenryHu 1 wikitext text/x-wiki Chrome App不算Desktop Client。 Facebook Messenger用的是MQTT协议,居然还是ISO标准…… QQ For Linux 这种古董还是算了…… Encrypted 指 End-to-End Encrypted。 Skype for Linux? 呵呵呵…… {| class="wikitable sortable" |- ! App !! Open Proto.!! Web !!Windows!! *nix !! Open Source !!Android!!Encrypted!! Distributed !! Group |- | Google Hangouts || {{No}} ||{{Yes}}||{{No}} || {{No}}|| {{No}} ||{{Yes}}||{{No}} || {{No}} ||{{Yes}} |- | Telegram || {{Yes}} ||{{Yes}}||{{Yes}}||{{Yes}}|| {{Yes}} ||{{Yes}}||{{Optional}}|| {{No}} ||{{Yes}} |- | Signal || {{Yes}} ||{{No}} || {{No}}||{{No}} || {{Yes}} ||{{Yes}}||{{Yes}} || {{No}} ||{{Yes}} |- | WhatsApp || {{Yes}} ||{{Yes}}||{{Yes}}|| || {{No}} ||{{Yes}}|| {{Yes}} || {{No}} ||{{Yes}} |- | Facebook Messenger|| {{Yes}} ||{{Yes}}||{{Yes}}|| || {{No}} ||{{Yes}}||{{Optional}}|| {{No}} ||{{Yes}} |- | iMessage || {{No}} ||{{No}} ||{{No}} ||{{No}} || {{No}} ||{{No}} || {{Yes}} || {{No}} ||{{Yes}} |- | QQ || {{No}} ||{{Yes}}||{{Yes}}||{{No}} || {{No}} ||{{Yes}}||{{No}} || {{No}} ||{{Yes}} |- | WeChat || {{No}} ||{{Yes}}||{{Yes}}||{{Optional|3rd-party}} || {{No}} ||{{Yes}}||{{No}} || {{No}} ||{{Yes}} |- | Skype || {{No}} ||{{Yes}}||{{Yes}}||{{No}} || {{No}} ||{{Yes}}||{{No}} || {{No}} ||{{Yes}} |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |} 34d57e50cdaabd0473c839c27de3a1982c7a5bb0 570 568 2017-01-26T01:12:46Z HenryHu 1 add Tox wikitext text/x-wiki Chrome App不算Desktop Client。 Facebook Messenger用的是MQTT协议,居然还是ISO标准…… QQ For Linux 这种古董还是算了…… Encrypted 指 End-to-End Encrypted。 Skype for Linux? 呵呵呵…… {| class="wikitable sortable" |- ! App !! Open Proto.!! Web !!Windows!! *nix !! Open Source !!Android!!Encrypted!! Distributed !! Group |- | Google Hangouts || {{No}} ||{{Yes}}||{{No}} || {{No}}|| {{No}} ||{{Yes}}||{{No}} || {{No}} ||{{Yes}} |- | Telegram || {{Yes}} ||{{Yes}}||{{Yes}}||{{Yes}}|| {{Yes}} ||{{Yes}}||{{Optional}}|| {{No}} ||{{Yes}} |- | Signal || {{Yes}} ||{{No}} || {{No}}||{{No}} || {{Yes}} ||{{Yes}}||{{Yes}} || {{No}} ||{{Yes}} |- | WhatsApp || {{Yes}} ||{{Yes}}||{{Yes}}|| || {{No}} ||{{Yes}}|| {{Yes}} || {{No}} ||{{Yes}} |- | Facebook Messenger|| {{Yes}} ||{{Yes}}||{{Yes}}|| || {{No}} ||{{Yes}}||{{Optional}}|| {{No}} ||{{Yes}} |- | iMessage || {{No}} ||{{No}} ||{{No}} ||{{No}} || {{No}} ||{{No}} || {{Yes}} || {{No}} ||{{Yes}} |- | QQ || {{No}} ||{{Yes}}||{{Yes}}||{{No}} || {{No}} ||{{Yes}}||{{No}} || {{No}} ||{{Yes}} |- | WeChat || {{No}} ||{{Yes}}||{{Yes}}||{{Optional|3rd-party}} || {{No}} ||{{Yes}}||{{No}} || {{No}} ||{{Yes}} |- | Skype || {{No}} ||{{Yes}}||{{Yes}}||{{No}} || {{No}} ||{{Yes}}||{{No}} || {{No}} ||{{Yes}} |- | Tox || {{Yes}} ||{{No}} ||{{Yes}}||{{Yes}}|| {{Yes}} ||{{Yes}}||{{Yes}} || {{Yes}} ||{{Yes}} |} 6093eb480b0328d5699048b8b398cd7741586987 Laziness Score 0 165 569 2017-01-14T05:49:21Z HenryHu 1 创建页面,内容为“{| class="wikitable" |- ! Activity !! Score !! 标题文字 |- | Unplug & Plug || 1 || 示例 |- | Take sth. with you || 2 || 示例...” wikitext text/x-wiki {| class="wikitable" |- ! Activity !! Score !! 标题文字 |- | Unplug & Plug || 1 || 示例 |- | Take sth. with you || 2 || 示例 |- | Pair manually || 3 || 示例 |- | Match numbers || 3 || 示例 |- | Match patterns || 4 || 示例 |- | Enter numbers || 4 || 示例 |- | Install app || 5 || 示例 |- | 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 |} a797830ca5bfa113fd06b65a91a5b516808e5e50 Windows Services 0 166 571 2017-02-18T05:30:13Z HenryHu 1 创建页面,内容为“If you need to do some remote assistance... sc query <servicename> Query the service status. sc qc <servicename> Query the service configuration, includi...” wikitext text/x-wiki If you need to do some remote assistance... sc query <servicename> Query the service status. sc qc <servicename> Query the service configuration, including start option and dependencies. sc start <servicename> Start a service. Must be enabled first, and all dependencies must be started/enabled. sc config <servicename> start=auto Change the start option of a service to auto. If the start option is disabled, a service cannot be started. e86258f5bf1234ddd90a313c08c7ccd41f84bc12 Audio Forwarding 0 167 572 2017-04-09T05:35:06Z HenryHu 1 创建页面,内容为“Forward audio == Using Icecast == 1. Install a loopback sound driver, like VB-Audio. You would get a virtual playback device and a virtual recording device. Set th...” wikitext text/x-wiki Forward audio == Using Icecast == 1. Install a loopback sound driver, like VB-Audio. You would get a virtual playback device and a virtual recording device. Set the virtual playback device as default. 2. Install and setup Icecast server. 3. Install an Icecast source application. I'm using butt (https://danielnoethen.de/). Go to butt's settings, and configure the server and stream info. Then go to the Audio tab and set the input to be the virtual recording device, also, increase the audio quality. 4. Listen to the stream on the host machine. You're done! 76a6bc86f48eb4202fb75c56bddce8bff7916ca8 Streaming Video 0 168 573 2017-05-28T01:28:53Z HenryHu 1 创建页面,内容为“{| class="wikitable sortable" |- ! Service !! Charge !! Description !! DRM !! 标题文字 !! 标题文字 |- | Amazon Video || || Included in Prime || Widevine ||...” wikitext text/x-wiki {| class="wikitable sortable" |- ! Service !! Charge !! Description !! DRM !! 标题文字 !! 标题文字 |- | Amazon Video || || Included in Prime || Widevine || Widevine || 示例 |- | Netflix || 7.99/m || Netflix! || Yes || 示例 || 示例 |- | HBO Now || 14.99/m || HBO programs: Silicon Valley || 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |} 5ac3aede5c90ff769c589b57335c1c88f8b95b8f 574 573 2017-05-28T02:58:32Z HenryHu 1 wikitext text/x-wiki {| class="wikitable sortable" |- ! Service !! Charge !! Description !! DRM !! 标题文字 !! 标题文字 |- | Amazon Video || || Included in Prime || Widevine || Widevine || 示例 |- | Netflix || 7.99/m || Netflix! || Yes || 示例 || 示例 |- | HBO Now || 14.99/m || HBO programs: Silicon Valley || 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |- | Crunchyroll || 6.95/m || Mostly animations and mangas || 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |- | 示例 || 示例 || 示例 || 示例 || 示例 || 示例 |} bedf68e14fce6462328ce3257721f1f2d4cf6105 Notes on STL 0 169 575 2017-07-29T02:25:46Z HenryHu 1 创建页面,内容为“== container == * begin(), end() * rbegin(), rend() * size() == vector == Resizable array. * Constructor: vector(), vector(size), vector(size, fill) * push_back(v...” wikitext text/x-wiki == container == * begin(), end() * rbegin(), rend() * size() == vector == Resizable array. * Constructor: vector(), vector(size), vector(size, fill) * push_back(val) * pop_back() == list == Implements double-linked list. * insert(it) Insert before it. it == end(): insert at the end. * erase(it) Erase item at it. Return item after it. == string == * Constructor: string(size, fill) * length() * substr(begin), substr(begin, count) Obtain a substring. == set / unordered_set == * insert(val) * erase(val), erase(it) * find(val) Return it, or end() if not found * count(val) == map == * insert(pair(key, val)) * at(key) Return val, throws if missing. * find(key) Return it, or end() if not found fe411e6e14d5a124d3fcfa68bef8c4308281a2a3 576 575 2017-07-29T04:03:33Z HenryHu 1 wikitext text/x-wiki == container == * begin(), end() * rbegin(), rend() * size() == vector == Resizable array. * Constructor: vector(), vector(size), vector(size, fill) * push_back(val) * pop_back() == list == Implements double-linked list. * insert(it) Insert before it. it == end(): insert at the end. * erase(it) Erase item at it. Return item after it. * front(), back() Easily access first & last element. == string == * Constructor: string(size, fill) * length() * substr(begin), substr(begin, count) Obtain a substring. == set / unordered_set == * insert(val) * erase(val), erase(it) * find(val) Return it, or end() if not found * count(val) * begin(), rbegin() Access min/max element. set only. == map == * insert(pair(key, val)) * at(key) Return val, throws if missing. * find(key) Return it, or end() if not found 881d6a06617eaa095b47a2d5e557b2bf48dfd8db Canon TS9020 0 170 577 2018-01-04T21:59:02Z HenryHu 1 创建页面,内容为“How to use Canon TS9020 on freebsd. == Printing == You can use the Linux driver on FreeBSD. Copy the files into proper places. cups' filters and backends should be...” wikitext text/x-wiki How to use Canon TS9020 on freebsd. == Printing == You can use the Linux driver on FreeBSD. Copy the files into proper places. cups' filters and backends should be copied into /usr/local/. Executables and libraries should be copied into /compat/linux. == Scanning == Scangearmp2 includes 3 binary blobs: libcncpnet30.so, libcncpnet20.so and libcncpmslld2.so. First 2 seems to be communication frameworks, while the third one contains scanner commands. I guess the scanner commands are the same as ones in sane's pixma backends. The only problem is the communication layer. It is no longer BJNP. It seems like that the libcncpnet30.so corresponds to the new communication layer which is used by TS9020. === Initial results === Something like endpoints appear in that so. I tried and it seems to be endpoints. <source> > curl -v http://192.168.1.127/canon/ij/command1/port1 * Trying 192.168.1.127... * TCP_NODELAY set * Connected to 192.168.1.127 (192.168.1.127) port 80 (#0) > GET /canon/ij/command1/port1 HTTP/1.1 > Host: 192.168.1.127 > User-Agent: curl/7.57.0 > Accept: */* > < HTTP/1.1 406 Not Acceptable < MIME-Version: 1.0 < Server: KS_HTTP/1.0 < Connection: Keep-Alive < X-CHMP-Version: 1.0.0 </source> The new protocol may be called CHMP, version 1.0.0. 0ec8f68160643e70ee98f2f745378581be050830 578 577 2018-01-04T22:08:10Z HenryHu 1 /* Initial results */ wikitext text/x-wiki How to use Canon TS9020 on freebsd. == Printing == You can use the Linux driver on FreeBSD. Copy the files into proper places. cups' filters and backends should be copied into /usr/local/. Executables and libraries should be copied into /compat/linux. == Scanning == Scangearmp2 includes 3 binary blobs: libcncpnet30.so, libcncpnet20.so and libcncpmslld2.so. First 2 seems to be communication frameworks, while the third one contains scanner commands. I guess the scanner commands are the same as ones in sane's pixma backends. The only problem is the communication layer. It is no longer BJNP. It seems like that the libcncpnet30.so corresponds to the new communication layer which is used by TS9020. === Initial results === Something like endpoints appear in that so. I tried and it seems to be endpoints. <source> > curl -v http://192.168.1.127/canon/ij/command1/port1 * Trying 192.168.1.127... * TCP_NODELAY set * Connected to 192.168.1.127 (192.168.1.127) port 80 (#0) > GET /canon/ij/command1/port1 HTTP/1.1 > Host: 192.168.1.127 > User-Agent: curl/7.57.0 > Accept: */* > < HTTP/1.1 406 Not Acceptable < MIME-Version: 1.0 < Server: KS_HTTP/1.0 < Connection: Keep-Alive < X-CHMP-Version: 1.0.0 </source> The new protocol may be called CHMP, version 1.0.0. Available endpoints: command1: port1-2 command2: port1-3 command1/port1 seems to return Conflict for POST cmds. 7cb56a9cfbb0d3151d36ee9b4cf7909498d98cfe Remote assistant tips 0 171 579 2018-06-24T03:24:13Z HenryHu 1 创建页面,内容为“Tips for remote assistant == Check WiFi frequency use adb == adb shell iw dev wlan0 link This gives you frequency. Check any table, or use "adb shell iw phy ph...” wikitext text/x-wiki Tips for remote assistant == Check WiFi frequency use adb == adb shell iw dev wlan0 link This gives you frequency. Check any table, or use "adb shell iw phy phy0 info" to find out the channel. Specifically, Channel 13 = 2472. d44a8ef35381be2501e85a9808785455b4ca8063 Monitor 0 172 580 2020-06-04T14:49:21Z HenryHu 1 创建页面,内容为“= 显示器挑选 = 显示器有若干参数,影响挑选。 == 颜色范围 == 各个显示器会标注各种能够显示的颜色范围。本文综述常见表…” wikitext text/x-wiki = 显示器挑选 = 显示器有若干参数,影响挑选。 == 颜色范围 == 各个显示器会标注各种能够显示的颜色范围。本文综述常见表示方法和范围。 参见:[https://www.msi.com/blog/why-dci-p3-is-the-new-standard-of-color-gamut Why DCI-P3 is the New Standard of Color Gamut?] === 常见描述 === * CIE 1931: 描述了所有人眼可见范围。定义了坐标系。 * sRGB: 古代标准,现在基本上各种显示器都支持99%或者100% sRGB。 * NTSC: 比 sRGB 大不少,72% NTSC ~ 99% sRGB。 * Adobe RGB: 高级货,和 NTSC 差不多,某些部分稍微大一点。覆盖大约 52.1% 的可见范围。 * DCI-P3: 比 sRGB 大一点(25%),比 NTSC 稍微小一点(4%),新标准。覆盖大约 45.5% 的可见范围。 === 判断 === * 如果只说 72% ~ 75% 那基本就是说 NTSC 的百分比了。 * 新的也有说 DCI-P3 9x% 的。 * 如果说了多个的(比如 sRGB 99%,DCI-P3 95%)可能是因为前面的又没盖全,但是又多出来不少。 2e589122aa855c5ced76b65e56838f9c3b3ed5e2 GPU Passthrough 0 173 581 2020-10-10T21:11:52Z HenryHu 1 创建页面,内容为“== 目标 == 在 Windows VM 中使用 GPU。 == 方法 == Passthrough GPU。 其实 Linux 那边有很成熟的方法了,不过 FreeBSD 这边还有问题。 ==…” wikitext text/x-wiki == 目标 == 在 Windows VM 中使用 GPU。 == 方法 == Passthrough GPU。 其实 Linux 那边有很成熟的方法了,不过 FreeBSD 这边还有问题。 == MMIO == NVidia 显卡有4个BAR: * 16M 的BAR0,据说有各种控制寄存器,主要控制接口。 * 256M 的BAR1,据说是显存窗口。 * 32M 的BAR3,据说其实也是显存窗口。 * 128 字节的IO Ports,据说可以在实模式访问显存。 == Interrupt == === MSI === == 验证 == Guest to Card: 已确认,Guest中访问mapped bar符合host访问结果 MSI: nouveau可正常设置中断,有中断产生。 == 问题 == 目前载入nouveau经常碰到的问题是初始化失败:在gp102_disp_dmac_init()里面,会有初始化超时。 这个超时貌似是在初始化DMA channel之后,等待DMA引擎空闲超时。看来DMA那边还是有问题。 == 参考资料 == Envytools: https://media.readthedocs.org/pdf/envytools/latest/envytools.pdf b233b116dd04e0b04b7247bfc19e6864b22cdb4c My Stuff 0 174 582 2020-11-11T17:46:04Z HenryHu 1 创建页面,内容为“= My Stuff = == 外设 == === 显示器 === * HP Envy 27 27 寸,IPS 面板,4K 输入:HDMI 1.4, HDMI 1.2,DP,USB-C * Dell U2720Q 27 寸,IPS 面板,4K…” wikitext text/x-wiki = My Stuff = == 外设 == === 显示器 === * HP Envy 27 27 寸,IPS 面板,4K 输入:HDMI 1.4, HDMI 1.2,DP,USB-C * Dell U2720Q 27 寸,IPS 面板,4K 输入:HDMI,DP,USB-C * Dell SE2716H 27 寸,VA 面板,2K,曲面 输入:HDMI x 2,VGA * ViewSonic x2 21.5 寸,VA 面板,2K === 鼠标 === * Logitech G604 无线 * Logitech G602 无线 * Logitech G500 有线 * Logitech G700 无线 === 键盘 === * Filco Majestouch 2 红轴,TenKeyLess * WASD Keyboard V2 青轴,TenKeyLess * DasKeyboard 青轴,全尺寸 * DasKeyboard 全尺寸 === 摄像头 === * Microsoft HD3000 * Logitech C922 Pro == 智能产品 == === 智能手表 === * Moto 360 (Battery dead) * Fossil Gen 5 === 智能灯泡 === * TP-Link KL110 * TP-Link LB130 === 智能插座 === * TP-Link * Monoprice === 智能家居 === * Google Home Hub * Google Home Mini * Nest Mini == 主机 == === 平板/笔记本 === * Surface 3 * Surface Pro 4 * Surface Pro 6 * Pixel C (Battery dead) * Pixel Slate * Nexus 7 2013 (Battery dead) * Nexus 7 2012 * Nexus 9 (Sold) * 小新平板 === 台式机 === * goldpeak ** CPU: Intel i7-7700K ** Mem: 4 x 8GB DDR4 ** MB: ASUS PRIME Z270-A [芯片组: Z270] ** NVME: Intel 660p 1TB ** NVME: WD Black SN750 1TB ** HDD: Seagate ST9500325AS 500GB [Seagate Momentus 5400.6, 5400 RPM, 8MB Cache, 2.5'] * brisk ** CPU: Intel i5-2500 ** Mem: 2x 4GB DDR3, 2x 8GB DDR3 ** MB: ASUS P8P67 LE [芯片组:P67] ** NVME: Sandisk Ultra 1TB ** SSD: OCZ Vortex 128GB * dew [Dell Wyse Zx0Q-7020] ** CPU: AMD GX-420CA ** Mem: 2x 4GB DDR3 ** SSD: 32GB * trek [Dell Optiplex 7040] ** CPU: Intel i5-6500T ** Mem: 2x 8GB DDR3 ** SSD: Kingston A400 240GB === 小型设备 === * Pine A64 * Pocket Chip 51b45a51596255ed60f1ef19fc107c5d40d8286a 583 582 2020-11-11T17:47:45Z HenryHu 1 /* 鼠标 */ wikitext text/x-wiki = My Stuff = == 外设 == === 显示器 === * HP Envy 27 27 寸,IPS 面板,4K 输入:HDMI 1.4, HDMI 1.2,DP,USB-C * Dell U2720Q 27 寸,IPS 面板,4K 输入:HDMI,DP,USB-C * Dell SE2716H 27 寸,VA 面板,2K,曲面 输入:HDMI x 2,VGA * ViewSonic x2 21.5 寸,VA 面板,2K === 鼠标 === * Logitech G604 无线 * Logitech G602 无线 * Logitech G500 有线 * Logitech G700 无线 * Logitech M570 无线,轨迹球 === 键盘 === * Filco Majestouch 2 红轴,TenKeyLess * WASD Keyboard V2 青轴,TenKeyLess * DasKeyboard 青轴,全尺寸 * DasKeyboard 全尺寸 === 摄像头 === * Microsoft HD3000 * Logitech C922 Pro == 智能产品 == === 智能手表 === * Moto 360 (Battery dead) * Fossil Gen 5 === 智能灯泡 === * TP-Link KL110 * TP-Link LB130 === 智能插座 === * TP-Link * Monoprice === 智能家居 === * Google Home Hub * Google Home Mini * Nest Mini == 主机 == === 平板/笔记本 === * Surface 3 * Surface Pro 4 * Surface Pro 6 * Pixel C (Battery dead) * Pixel Slate * Nexus 7 2013 (Battery dead) * Nexus 7 2012 * Nexus 9 (Sold) * 小新平板 === 台式机 === * goldpeak ** CPU: Intel i7-7700K ** Mem: 4 x 8GB DDR4 ** MB: ASUS PRIME Z270-A [芯片组: Z270] ** NVME: Intel 660p 1TB ** NVME: WD Black SN750 1TB ** HDD: Seagate ST9500325AS 500GB [Seagate Momentus 5400.6, 5400 RPM, 8MB Cache, 2.5'] * brisk ** CPU: Intel i5-2500 ** Mem: 2x 4GB DDR3, 2x 8GB DDR3 ** MB: ASUS P8P67 LE [芯片组:P67] ** NVME: Sandisk Ultra 1TB ** SSD: OCZ Vortex 128GB * dew [Dell Wyse Zx0Q-7020] ** CPU: AMD GX-420CA ** Mem: 2x 4GB DDR3 ** SSD: 32GB * trek [Dell Optiplex 7040] ** CPU: Intel i5-6500T ** Mem: 2x 8GB DDR3 ** SSD: Kingston A400 240GB === 小型设备 === * Pine A64 * Pocket Chip 6b52b5dbd1eacedf83f6c6108e647b17402e7e43 584 583 2020-11-11T17:51:20Z HenryHu 1 /* 台式机 */ wikitext text/x-wiki = My Stuff = == 外设 == === 显示器 === * HP Envy 27 27 寸,IPS 面板,4K 输入:HDMI 1.4, HDMI 1.2,DP,USB-C * Dell U2720Q 27 寸,IPS 面板,4K 输入:HDMI,DP,USB-C * Dell SE2716H 27 寸,VA 面板,2K,曲面 输入:HDMI x 2,VGA * ViewSonic x2 21.5 寸,VA 面板,2K === 鼠标 === * Logitech G604 无线 * Logitech G602 无线 * Logitech G500 有线 * Logitech G700 无线 * Logitech M570 无线,轨迹球 === 键盘 === * Filco Majestouch 2 红轴,TenKeyLess * WASD Keyboard V2 青轴,TenKeyLess * DasKeyboard 青轴,全尺寸 * DasKeyboard 全尺寸 === 摄像头 === * Microsoft HD3000 * Logitech C922 Pro == 智能产品 == === 智能手表 === * Moto 360 (Battery dead) * Fossil Gen 5 === 智能灯泡 === * TP-Link KL110 * TP-Link LB130 === 智能插座 === * TP-Link * Monoprice === 智能家居 === * Google Home Hub * Google Home Mini * Nest Mini == 主机 == === 平板/笔记本 === * Surface 3 * Surface Pro 4 * Surface Pro 6 * Pixel C (Battery dead) * Pixel Slate * Nexus 7 2013 (Battery dead) * Nexus 7 2012 * Nexus 9 (Sold) * 小新平板 === 台式机 === * goldpeak ** CPU: Intel i7-7700K ** Mem: 4 x 8GB DDR4 ** MB: ASUS PRIME Z270-A [芯片组: Z270] ** NVME: Intel 660p 1TB ** NVME: WD Black SN750 1TB ** HDD: Seagate ST9500325AS 500GB [Seagate Momentus 5400.6, 5400 RPM, 8MB Cache, 2.5'] * brisk ** CPU: Intel i5-2500 ** Mem: 2x 4GB DDR3, 2x 8GB DDR3 ** MB: ASUS P8P67 LE [芯片组:P67] ** NVME: Sandisk Ultra 1TB ** SSD: OCZ Vortex 128GB * dew [Dell Wyse Zx0Q-7020] ** CPU: AMD GX-420CA ** Mem: 2x 4GB DDR3 ** SSD: 32GB * trek [Dell Optiplex 7040] ** CPU: Intel i5-6500T ** Mem: 2x 8GB DDR3 ** SSD: Kingston A400 240GB * nas ** CPU: Intel Pentium G4560 ** Mem: 2x 8GB DDR4 ** MB: ASUS H110I-PLUS ** SSD: HP SSD S700 120GB ** HDD: 3x WD Red WD40EFRX 4TB === 小型设备 === * Pine A64 * Pocket Chip b0f3065b021c7f60615de43b06864696c29eef90 585 584 2020-11-11T18:03:28Z HenryHu 1 /* 台式机 */ wikitext text/x-wiki = My Stuff = == 外设 == === 显示器 === * HP Envy 27 27 寸,IPS 面板,4K 输入:HDMI 1.4, HDMI 1.2,DP,USB-C * Dell U2720Q 27 寸,IPS 面板,4K 输入:HDMI,DP,USB-C * Dell SE2716H 27 寸,VA 面板,2K,曲面 输入:HDMI x 2,VGA * ViewSonic x2 21.5 寸,VA 面板,2K === 鼠标 === * Logitech G604 无线 * Logitech G602 无线 * Logitech G500 有线 * Logitech G700 无线 * Logitech M570 无线,轨迹球 === 键盘 === * Filco Majestouch 2 红轴,TenKeyLess * WASD Keyboard V2 青轴,TenKeyLess * DasKeyboard 青轴,全尺寸 * DasKeyboard 全尺寸 === 摄像头 === * Microsoft HD3000 * Logitech C922 Pro == 智能产品 == === 智能手表 === * Moto 360 (Battery dead) * Fossil Gen 5 === 智能灯泡 === * TP-Link KL110 * TP-Link LB130 === 智能插座 === * TP-Link * Monoprice === 智能家居 === * Google Home Hub * Google Home Mini * Nest Mini == 主机 == === 平板/笔记本 === * Surface 3 * Surface Pro 4 * Surface Pro 6 * Pixel C (Battery dead) * Pixel Slate * Nexus 7 2013 (Battery dead) * Nexus 7 2012 * Nexus 9 (Sold) * 小新平板 === 台式机 === * goldpeak ** CPU: Intel i7-7700K ** Mem: 4 x 8GB DDR4 ** MB: ASUS PRIME Z270-A [芯片组: Z270] ** NVME: Intel 660p 1TB ** NVME: WD Black SN750 1TB ** HDD: Seagate ST9500325AS 500GB [Seagate Momentus 5400.6, 5400 RPM, 8MB Cache, 2.5'] * brisk ** CPU: Intel i5-2500 ** Mem: 2x 4GB DDR3, 2x 8GB DDR3 ** MB: ASUS P8P67 LE [芯片组:P67] ** NVME: Sandisk Ultra 1TB ** SSD: OCZ Vortex 128GB * dew [Dell Wyse Zx0Q-7020] ** CPU: AMD GX-420CA ** Mem: 2x 4GB DDR3 ** SSD: 32GB * trek [Dell Optiplex 7040] ** CPU: Intel i5-6500T ** Mem: 2x 8GB DDR4 ** SSD: Kingston A400 240GB * nas ** CPU: Intel Pentium G4560 ** Mem: 2x 8GB DDR4 ** MB: ASUS H110I-PLUS ** SSD: HP SSD S700 120GB ** HDD: 3x WD Red WD40EFRX 4TB === 小型设备 === * Pine A64 * Pocket Chip 918d1e2f54bc83c70d79fc9be9fd357bec45d792 586 585 2020-11-11T20:29:55Z HenryHu 1 /* 智能插座 */ wikitext text/x-wiki = My Stuff = == 外设 == === 显示器 === * HP Envy 27 27 寸,IPS 面板,4K 输入:HDMI 1.4, HDMI 1.2,DP,USB-C * Dell U2720Q 27 寸,IPS 面板,4K 输入:HDMI,DP,USB-C * Dell SE2716H 27 寸,VA 面板,2K,曲面 输入:HDMI x 2,VGA * ViewSonic x2 21.5 寸,VA 面板,2K === 鼠标 === * Logitech G604 无线 * Logitech G602 无线 * Logitech G500 有线 * Logitech G700 无线 * Logitech M570 无线,轨迹球 === 键盘 === * Filco Majestouch 2 红轴,TenKeyLess * WASD Keyboard V2 青轴,TenKeyLess * DasKeyboard 青轴,全尺寸 * DasKeyboard 全尺寸 === 摄像头 === * Microsoft HD3000 * Logitech C922 Pro == 智能产品 == === 智能手表 === * Moto 360 (Battery dead) * Fossil Gen 5 === 智能灯泡 === * TP-Link KL110 * TP-Link LB130 === 智能插座 === * TP-Link HS100 * Monoprice === 智能家居 === * Google Home Hub * Google Home Mini * Nest Mini == 主机 == === 平板/笔记本 === * Surface 3 * Surface Pro 4 * Surface Pro 6 * Pixel C (Battery dead) * Pixel Slate * Nexus 7 2013 (Battery dead) * Nexus 7 2012 * Nexus 9 (Sold) * 小新平板 === 台式机 === * goldpeak ** CPU: Intel i7-7700K ** Mem: 4 x 8GB DDR4 ** MB: ASUS PRIME Z270-A [芯片组: Z270] ** NVME: Intel 660p 1TB ** NVME: WD Black SN750 1TB ** HDD: Seagate ST9500325AS 500GB [Seagate Momentus 5400.6, 5400 RPM, 8MB Cache, 2.5'] * brisk ** CPU: Intel i5-2500 ** Mem: 2x 4GB DDR3, 2x 8GB DDR3 ** MB: ASUS P8P67 LE [芯片组:P67] ** NVME: Sandisk Ultra 1TB ** SSD: OCZ Vortex 128GB * dew [Dell Wyse Zx0Q-7020] ** CPU: AMD GX-420CA ** Mem: 2x 4GB DDR3 ** SSD: 32GB * trek [Dell Optiplex 7040] ** CPU: Intel i5-6500T ** Mem: 2x 8GB DDR4 ** SSD: Kingston A400 240GB * nas ** CPU: Intel Pentium G4560 ** Mem: 2x 8GB DDR4 ** MB: ASUS H110I-PLUS ** SSD: HP SSD S700 120GB ** HDD: 3x WD Red WD40EFRX 4TB === 小型设备 === * Pine A64 * Pocket Chip 4681ec9ffbe319d0df9b5ea6a2b37bc778f9f20c 587 586 2020-11-11T20:36:24Z HenryHu 1 /* 键盘 */ wikitext text/x-wiki = My Stuff = == 外设 == === 显示器 === * HP Envy 27 27 寸,IPS 面板,4K 输入:HDMI 1.4, HDMI 1.2,DP,USB-C * Dell U2720Q 27 寸,IPS 面板,4K 输入:HDMI,DP,USB-C * Dell SE2716H 27 寸,VA 面板,2K,曲面 输入:HDMI x 2,VGA * ViewSonic x2 21.5 寸,VA 面板,2K === 鼠标 === * Logitech G604 无线 * Logitech G602 无线 * Logitech G500 有线 * Logitech G700 无线 * Logitech M570 无线,轨迹球 === 键盘 === ==== 有线 ==== * Filco Majestouch 2 红轴,TenKeyLess * WASD Keyboard V2 青轴,TenKeyLess * DasKeyboard 青轴,全尺寸 * DasKeyboard 全尺寸 * Rosewill RK-9000V2 黑轴,全尺寸 * Dell Stock Keyboard 薄膜键盘,全尺寸 ==== 无线 ==== * Logitech K480 3设备 * Logitech K270 全尺寸 * Microsoft Universal Mobile Keyboard 3设备 * Motorola Wireless Keyboard === 摄像头 === * Microsoft HD3000 * Logitech C922 Pro == 智能产品 == === 智能手表 === * Moto 360 (Battery dead) * Fossil Gen 5 === 智能灯泡 === * TP-Link KL110 * TP-Link LB130 === 智能插座 === * TP-Link HS100 * Monoprice === 智能家居 === * Google Home Hub * Google Home Mini * Nest Mini == 主机 == === 平板/笔记本 === * Surface 3 * Surface Pro 4 * Surface Pro 6 * Pixel C (Battery dead) * Pixel Slate * Nexus 7 2013 (Battery dead) * Nexus 7 2012 * Nexus 9 (Sold) * 小新平板 === 台式机 === * goldpeak ** CPU: Intel i7-7700K ** Mem: 4 x 8GB DDR4 ** MB: ASUS PRIME Z270-A [芯片组: Z270] ** NVME: Intel 660p 1TB ** NVME: WD Black SN750 1TB ** HDD: Seagate ST9500325AS 500GB [Seagate Momentus 5400.6, 5400 RPM, 8MB Cache, 2.5'] * brisk ** CPU: Intel i5-2500 ** Mem: 2x 4GB DDR3, 2x 8GB DDR3 ** MB: ASUS P8P67 LE [芯片组:P67] ** NVME: Sandisk Ultra 1TB ** SSD: OCZ Vortex 128GB * dew [Dell Wyse Zx0Q-7020] ** CPU: AMD GX-420CA ** Mem: 2x 4GB DDR3 ** SSD: 32GB * trek [Dell Optiplex 7040] ** CPU: Intel i5-6500T ** Mem: 2x 8GB DDR4 ** SSD: Kingston A400 240GB * nas ** CPU: Intel Pentium G4560 ** Mem: 2x 8GB DDR4 ** MB: ASUS H110I-PLUS ** SSD: HP SSD S700 120GB ** HDD: 3x WD Red WD40EFRX 4TB === 小型设备 === * Pine A64 * Pocket Chip 6b1db31a5e6ce0bc48e8eedf081605284d2ab3a1 588 587 2020-11-11T20:38:14Z HenryHu 1 /* 鼠标 */ wikitext text/x-wiki = My Stuff = == 外设 == === 显示器 === * HP Envy 27 27 寸,IPS 面板,4K 输入:HDMI 1.4, HDMI 1.2,DP,USB-C * Dell U2720Q 27 寸,IPS 面板,4K 输入:HDMI,DP,USB-C * Dell SE2716H 27 寸,VA 面板,2K,曲面 输入:HDMI x 2,VGA * ViewSonic x2 21.5 寸,VA 面板,2K === 鼠标 === ==== 有线 ==== * Logitech G500 * Dell Stock Mouse ==== 无线 ==== * Logitech G604 * Logitech G602 * Logitech G700 * Logitech M310 * Logitech M545 * Logitech M570 轨迹球 * Logitech MX Ergo 轨迹球 * Logitech Trackman Marble === 键盘 === ==== 有线 ==== * Filco Majestouch 2 红轴,TenKeyLess * WASD Keyboard V2 青轴,TenKeyLess * DasKeyboard 青轴,全尺寸 * DasKeyboard 全尺寸 * Rosewill RK-9000V2 黑轴,全尺寸 * Dell Stock Keyboard 薄膜键盘,全尺寸 ==== 无线 ==== * Logitech K480 3设备 * Logitech K270 全尺寸 * Microsoft Universal Mobile Keyboard 3设备 * Motorola Wireless Keyboard === 摄像头 === * Microsoft HD3000 * Logitech C922 Pro == 智能产品 == === 智能手表 === * Moto 360 (Battery dead) * Fossil Gen 5 === 智能灯泡 === * TP-Link KL110 * TP-Link LB130 === 智能插座 === * TP-Link HS100 * Monoprice === 智能家居 === * Google Home Hub * Google Home Mini * Nest Mini == 主机 == === 平板/笔记本 === * Surface 3 * Surface Pro 4 * Surface Pro 6 * Pixel C (Battery dead) * Pixel Slate * Nexus 7 2013 (Battery dead) * Nexus 7 2012 * Nexus 9 (Sold) * 小新平板 === 台式机 === * goldpeak ** CPU: Intel i7-7700K ** Mem: 4 x 8GB DDR4 ** MB: ASUS PRIME Z270-A [芯片组: Z270] ** NVME: Intel 660p 1TB ** NVME: WD Black SN750 1TB ** HDD: Seagate ST9500325AS 500GB [Seagate Momentus 5400.6, 5400 RPM, 8MB Cache, 2.5'] * brisk ** CPU: Intel i5-2500 ** Mem: 2x 4GB DDR3, 2x 8GB DDR3 ** MB: ASUS P8P67 LE [芯片组:P67] ** NVME: Sandisk Ultra 1TB ** SSD: OCZ Vortex 128GB * dew [Dell Wyse Zx0Q-7020] ** CPU: AMD GX-420CA ** Mem: 2x 4GB DDR3 ** SSD: 32GB * trek [Dell Optiplex 7040] ** CPU: Intel i5-6500T ** Mem: 2x 8GB DDR4 ** SSD: Kingston A400 240GB * nas ** CPU: Intel Pentium G4560 ** Mem: 2x 8GB DDR4 ** MB: ASUS H110I-PLUS ** SSD: HP SSD S700 120GB ** HDD: 3x WD Red WD40EFRX 4TB === 小型设备 === * Pine A64 * Pocket Chip 232db4b6f34de8717653835831baaed58455663c 589 588 2020-11-11T20:48:57Z HenryHu 1 /* 平板/笔记本 */ wikitext text/x-wiki = My Stuff = == 外设 == === 显示器 === * HP Envy 27 27 寸,IPS 面板,4K 输入:HDMI 1.4, HDMI 1.2,DP,USB-C * Dell U2720Q 27 寸,IPS 面板,4K 输入:HDMI,DP,USB-C * Dell SE2716H 27 寸,VA 面板,2K,曲面 输入:HDMI x 2,VGA * ViewSonic x2 21.5 寸,VA 面板,2K === 鼠标 === ==== 有线 ==== * Logitech G500 * Dell Stock Mouse ==== 无线 ==== * Logitech G604 * Logitech G602 * Logitech G700 * Logitech M310 * Logitech M545 * Logitech M570 轨迹球 * Logitech MX Ergo 轨迹球 * Logitech Trackman Marble === 键盘 === ==== 有线 ==== * Filco Majestouch 2 红轴,TenKeyLess * WASD Keyboard V2 青轴,TenKeyLess * DasKeyboard 青轴,全尺寸 * DasKeyboard 全尺寸 * Rosewill RK-9000V2 黑轴,全尺寸 * Dell Stock Keyboard 薄膜键盘,全尺寸 ==== 无线 ==== * Logitech K480 3设备 * Logitech K270 全尺寸 * Microsoft Universal Mobile Keyboard 3设备 * Motorola Wireless Keyboard === 摄像头 === * Microsoft HD3000 * Logitech C922 Pro == 智能产品 == === 智能手表 === * Moto 360 (Battery dead) * Fossil Gen 5 === 智能灯泡 === * TP-Link KL110 * TP-Link LB130 === 智能插座 === * TP-Link HS100 * Monoprice === 智能家居 === * Google Home Hub * Google Home Mini * Nest Mini == 主机 == === 平板/笔记本 === * Motorola Xoom (dead) * Surface 3 * Surface Pro 4 * Surface Pro 6 * Pixel C (Battery dead) * Pixel Slate * Nexus 7 2013 (Battery dead) * Nexus 7 2012 * Nexus 9 (Sold) * 小新平板 === 台式机 === * goldpeak ** CPU: Intel i7-7700K ** Mem: 4 x 8GB DDR4 ** MB: ASUS PRIME Z270-A [芯片组: Z270] ** NVME: Intel 660p 1TB ** NVME: WD Black SN750 1TB ** HDD: Seagate ST9500325AS 500GB [Seagate Momentus 5400.6, 5400 RPM, 8MB Cache, 2.5'] * brisk ** CPU: Intel i5-2500 ** Mem: 2x 4GB DDR3, 2x 8GB DDR3 ** MB: ASUS P8P67 LE [芯片组:P67] ** NVME: Sandisk Ultra 1TB ** SSD: OCZ Vortex 128GB * dew [Dell Wyse Zx0Q-7020] ** CPU: AMD GX-420CA ** Mem: 2x 4GB DDR3 ** SSD: 32GB * trek [Dell Optiplex 7040] ** CPU: Intel i5-6500T ** Mem: 2x 8GB DDR4 ** SSD: Kingston A400 240GB * nas ** CPU: Intel Pentium G4560 ** Mem: 2x 8GB DDR4 ** MB: ASUS H110I-PLUS ** SSD: HP SSD S700 120GB ** HDD: 3x WD Red WD40EFRX 4TB === 小型设备 === * Pine A64 * Pocket Chip 2878bb92feba24a91bdc83fa25a9c05275aefd8d 590 589 2020-11-12T00:51:22Z HenryHu 1 /* 摄像头 */ wikitext text/x-wiki = My Stuff = == 外设 == === 显示器 === * HP Envy 27 27 寸,IPS 面板,4K 输入:HDMI 1.4, HDMI 1.2,DP,USB-C * Dell U2720Q 27 寸,IPS 面板,4K 输入:HDMI,DP,USB-C * Dell SE2716H 27 寸,VA 面板,2K,曲面 输入:HDMI x 2,VGA * ViewSonic x2 21.5 寸,VA 面板,2K === 鼠标 === ==== 有线 ==== * Logitech G500 * Dell Stock Mouse ==== 无线 ==== * Logitech G604 * Logitech G602 * Logitech G700 * Logitech M310 * Logitech M545 * Logitech M570 轨迹球 * Logitech MX Ergo 轨迹球 * Logitech Trackman Marble === 键盘 === ==== 有线 ==== * Filco Majestouch 2 红轴,TenKeyLess * WASD Keyboard V2 青轴,TenKeyLess * DasKeyboard 青轴,全尺寸 * DasKeyboard 全尺寸 * Rosewill RK-9000V2 黑轴,全尺寸 * Dell Stock Keyboard 薄膜键盘,全尺寸 ==== 无线 ==== * Logitech K480 3设备 * Logitech K270 全尺寸 * Microsoft Universal Mobile Keyboard 3设备 * Motorola Wireless Keyboard === 摄像头 === * Microsoft HD3000 * Logitech C922 Pro === 耳机 === ==== 大耳机 ==== * AKG K701 Open * Sennheiser HD598 Open * Sennheiser HD6XX (HD650) Open * Audio Technica ATH-PRO500MK2 Closed * Sony WH1000XM3 主动降噪,蓝牙 * Sennheiser HD201 * BeyerDynamics DT235 ==== 小耳机 ==== * Shure SE215 半个挂了 * Shure SE425 有线/蓝牙 * Sennheiser HD1 蓝牙 * Sennheiser MX475 * Anker Soundbuds Curve 蓝牙 * Audio Technica ATH-CKM500 * HifiMan Re-400 * Panasonic RP-HT21 * JVC HAF150B == 智能产品 == === 智能手表 === * Moto 360 (Battery dead) * Fossil Gen 5 === 智能灯泡 === * TP-Link KL110 * TP-Link LB130 === 智能插座 === * TP-Link HS100 * Monoprice === 智能家居 === * Google Home Hub * Google Home Mini * Nest Mini == 主机 == === 平板/笔记本 === * Motorola Xoom (dead) * Surface 3 * Surface Pro 4 * Surface Pro 6 * Pixel C (Battery dead) * Pixel Slate * Nexus 7 2013 (Battery dead) * Nexus 7 2012 * Nexus 9 (Sold) * 小新平板 === 台式机 === * goldpeak ** CPU: Intel i7-7700K ** Mem: 4 x 8GB DDR4 ** MB: ASUS PRIME Z270-A [芯片组: Z270] ** NVME: Intel 660p 1TB ** NVME: WD Black SN750 1TB ** HDD: Seagate ST9500325AS 500GB [Seagate Momentus 5400.6, 5400 RPM, 8MB Cache, 2.5'] * brisk ** CPU: Intel i5-2500 ** Mem: 2x 4GB DDR3, 2x 8GB DDR3 ** MB: ASUS P8P67 LE [芯片组:P67] ** NVME: Sandisk Ultra 1TB ** SSD: OCZ Vortex 128GB * dew [Dell Wyse Zx0Q-7020] ** CPU: AMD GX-420CA ** Mem: 2x 4GB DDR3 ** SSD: 32GB * trek [Dell Optiplex 7040] ** CPU: Intel i5-6500T ** Mem: 2x 8GB DDR4 ** SSD: Kingston A400 240GB * nas ** CPU: Intel Pentium G4560 ** Mem: 2x 8GB DDR4 ** MB: ASUS H110I-PLUS ** SSD: HP SSD S700 120GB ** HDD: 3x WD Red WD40EFRX 4TB === 小型设备 === * Pine A64 * Pocket Chip 3a4bdc354744833933f52483914840de2ac1d857 591 590 2020-11-12T01:36:12Z HenryHu 1 /* 小耳机 */ wikitext text/x-wiki = My Stuff = == 外设 == === 显示器 === * HP Envy 27 27 寸,IPS 面板,4K 输入:HDMI 1.4, HDMI 1.2,DP,USB-C * Dell U2720Q 27 寸,IPS 面板,4K 输入:HDMI,DP,USB-C * Dell SE2716H 27 寸,VA 面板,2K,曲面 输入:HDMI x 2,VGA * ViewSonic x2 21.5 寸,VA 面板,2K === 鼠标 === ==== 有线 ==== * Logitech G500 * Dell Stock Mouse ==== 无线 ==== * Logitech G604 * Logitech G602 * Logitech G700 * Logitech M310 * Logitech M545 * Logitech M570 轨迹球 * Logitech MX Ergo 轨迹球 * Logitech Trackman Marble === 键盘 === ==== 有线 ==== * Filco Majestouch 2 红轴,TenKeyLess * WASD Keyboard V2 青轴,TenKeyLess * DasKeyboard 青轴,全尺寸 * DasKeyboard 全尺寸 * Rosewill RK-9000V2 黑轴,全尺寸 * Dell Stock Keyboard 薄膜键盘,全尺寸 ==== 无线 ==== * Logitech K480 3设备 * Logitech K270 全尺寸 * Microsoft Universal Mobile Keyboard 3设备 * Motorola Wireless Keyboard === 摄像头 === * Microsoft HD3000 * Logitech C922 Pro === 耳机 === ==== 大耳机 ==== * AKG K701 Open * Sennheiser HD598 Open * Sennheiser HD6XX (HD650) Open * Audio Technica ATH-PRO500MK2 Closed * Sony WH1000XM3 主动降噪,蓝牙 * Sennheiser HD201 * BeyerDynamics DT235 ==== 小耳机 ==== * Shure SE215 半个挂了 * Shure SE425 有线/蓝牙 * Sennheiser HD1 蓝牙 * Sennheiser MX475 * Anker Soundbuds Curve 蓝牙 * Audio Technica ATH-CKM500 坏了 * HifiMan Re-400 坏了 * Panasonic RP-HT21 * JVC HAF150B == 智能产品 == === 智能手表 === * Moto 360 (Battery dead) * Fossil Gen 5 === 智能灯泡 === * TP-Link KL110 * TP-Link LB130 === 智能插座 === * TP-Link HS100 * Monoprice === 智能家居 === * Google Home Hub * Google Home Mini * Nest Mini == 主机 == === 平板/笔记本 === * Motorola Xoom (dead) * Surface 3 * Surface Pro 4 * Surface Pro 6 * Pixel C (Battery dead) * Pixel Slate * Nexus 7 2013 (Battery dead) * Nexus 7 2012 * Nexus 9 (Sold) * 小新平板 === 台式机 === * goldpeak ** CPU: Intel i7-7700K ** Mem: 4 x 8GB DDR4 ** MB: ASUS PRIME Z270-A [芯片组: Z270] ** NVME: Intel 660p 1TB ** NVME: WD Black SN750 1TB ** HDD: Seagate ST9500325AS 500GB [Seagate Momentus 5400.6, 5400 RPM, 8MB Cache, 2.5'] * brisk ** CPU: Intel i5-2500 ** Mem: 2x 4GB DDR3, 2x 8GB DDR3 ** MB: ASUS P8P67 LE [芯片组:P67] ** NVME: Sandisk Ultra 1TB ** SSD: OCZ Vortex 128GB * dew [Dell Wyse Zx0Q-7020] ** CPU: AMD GX-420CA ** Mem: 2x 4GB DDR3 ** SSD: 32GB * trek [Dell Optiplex 7040] ** CPU: Intel i5-6500T ** Mem: 2x 8GB DDR4 ** SSD: Kingston A400 240GB * nas ** CPU: Intel Pentium G4560 ** Mem: 2x 8GB DDR4 ** MB: ASUS H110I-PLUS ** SSD: HP SSD S700 120GB ** HDD: 3x WD Red WD40EFRX 4TB === 小型设备 === * Pine A64 * Pocket Chip 82d519d04311d2ef5c0c8982ecc8a4dba9d9de4f 592 591 2020-11-12T02:39:13Z HenryHu 1 /* 耳机 */ wikitext text/x-wiki = My Stuff = == 外设 == === 显示器 === * HP Envy 27 27 寸,IPS 面板,4K 输入:HDMI 1.4, HDMI 1.2,DP,USB-C * Dell U2720Q 27 寸,IPS 面板,4K 输入:HDMI,DP,USB-C * Dell SE2716H 27 寸,VA 面板,2K,曲面 输入:HDMI x 2,VGA * ViewSonic x2 21.5 寸,VA 面板,2K === 鼠标 === ==== 有线 ==== * Logitech G500 * Dell Stock Mouse ==== 无线 ==== * Logitech G604 * Logitech G602 * Logitech G700 * Logitech M310 * Logitech M545 * Logitech M570 轨迹球 * Logitech MX Ergo 轨迹球 * Logitech Trackman Marble === 键盘 === ==== 有线 ==== * Filco Majestouch 2 红轴,TenKeyLess * WASD Keyboard V2 青轴,TenKeyLess * DasKeyboard 青轴,全尺寸 * DasKeyboard 全尺寸 * Rosewill RK-9000V2 黑轴,全尺寸 * Dell Stock Keyboard 薄膜键盘,全尺寸 ==== 无线 ==== * Logitech K480 3设备 * Logitech K270 全尺寸 * Microsoft Universal Mobile Keyboard 3设备 * Motorola Wireless Keyboard === 摄像头 === * Microsoft HD3000 * Logitech C922 Pro === 耳机 === ==== 大耳机 ==== * AKG K701 Open * Sennheiser HD598 Open * Sennheiser HD6XX (HD650) Open * Audio Technica ATH-PRO500MK2 Closed * Sony WH1000XM3 主动降噪,蓝牙 * Sennheiser HD201 * BeyerDynamics DT235 * Panasonic RP-HT21 ==== 小耳机 ==== * Shure SE215 半个挂了 * Shure SE425 有线/蓝牙 * Sennheiser HD1 蓝牙 * Sennheiser MX475 * Anker Soundbuds Curve 蓝牙 * Audio Technica ATH-CKM500 坏了 * HifiMan Re-400 坏了 * JVC HAF150B == 智能产品 == === 智能手表 === * Moto 360 (Battery dead) * Fossil Gen 5 === 智能灯泡 === * TP-Link KL110 * TP-Link LB130 === 智能插座 === * TP-Link HS100 * Monoprice === 智能家居 === * Google Home Hub * Google Home Mini * Nest Mini == 主机 == === 平板/笔记本 === * Motorola Xoom (dead) * Surface 3 * Surface Pro 4 * Surface Pro 6 * Pixel C (Battery dead) * Pixel Slate * Nexus 7 2013 (Battery dead) * Nexus 7 2012 * Nexus 9 (Sold) * 小新平板 === 台式机 === * goldpeak ** CPU: Intel i7-7700K ** Mem: 4 x 8GB DDR4 ** MB: ASUS PRIME Z270-A [芯片组: Z270] ** NVME: Intel 660p 1TB ** NVME: WD Black SN750 1TB ** HDD: Seagate ST9500325AS 500GB [Seagate Momentus 5400.6, 5400 RPM, 8MB Cache, 2.5'] * brisk ** CPU: Intel i5-2500 ** Mem: 2x 4GB DDR3, 2x 8GB DDR3 ** MB: ASUS P8P67 LE [芯片组:P67] ** NVME: Sandisk Ultra 1TB ** SSD: OCZ Vortex 128GB * dew [Dell Wyse Zx0Q-7020] ** CPU: AMD GX-420CA ** Mem: 2x 4GB DDR3 ** SSD: 32GB * trek [Dell Optiplex 7040] ** CPU: Intel i5-6500T ** Mem: 2x 8GB DDR4 ** SSD: Kingston A400 240GB * nas ** CPU: Intel Pentium G4560 ** Mem: 2x 8GB DDR4 ** MB: ASUS H110I-PLUS ** SSD: HP SSD S700 120GB ** HDD: 3x WD Red WD40EFRX 4TB === 小型设备 === * Pine A64 * Pocket Chip 7d585fb3d920c5a563dec1e74cdd0d92a13aa059 594 592 2020-11-14T05:50:16Z HenryHu 1 /* 显示器 */ wikitext text/x-wiki = My Stuff = == 外设 == === 显示器 === * HP Envy 27 27 寸,IPS 面板,4K 输入:HDMI 1.4, HDMI 1.2,DP,USB-C * Dell U2720Q 27 寸,IPS 面板,4K 输入:HDMI,DP,USB-C * Dell SE2716H 27 寸,VA 面板,2K,曲面 输入:HDMI x 2,VGA * ViewSonic x2 21.5 寸,VA 面板,2K === 鼠标 === ==== 有线 ==== * Logitech G500 * Dell Stock Mouse ==== 无线 ==== * Logitech G604 * Logitech G602 * Logitech G700 * Logitech M310 * Logitech M545 * Logitech M570 轨迹球 * Logitech MX Ergo 轨迹球 * Logitech Trackman Marble === 键盘 === ==== 有线 ==== * Filco Majestouch 2 红轴,TenKeyLess * WASD Keyboard V2 青轴,TenKeyLess * DasKeyboard 青轴,全尺寸 * DasKeyboard 全尺寸 * Rosewill RK-9000V2 黑轴,全尺寸 * Dell Stock Keyboard 薄膜键盘,全尺寸 ==== 无线 ==== * Logitech K480 3设备 * Logitech K270 全尺寸 * Microsoft Universal Mobile Keyboard 3设备 * Motorola Wireless Keyboard === 摄像头 === * Microsoft HD3000 * Logitech C922 Pro === 耳机 === ==== 大耳机 ==== * AKG K701 Open * Sennheiser HD598 Open * Sennheiser HD6XX (HD650) Open * Audio Technica ATH-PRO500MK2 Closed * Sony WH1000XM3 主动降噪,蓝牙 * Sennheiser HD201 * BeyerDynamics DT235 * Panasonic RP-HT21 ==== 小耳机 ==== * Shure SE215 半个挂了 * Shure SE425 有线/蓝牙 * Sennheiser HD1 蓝牙 * Sennheiser MX475 * Anker Soundbuds Curve 蓝牙 * Audio Technica ATH-CKM500 坏了 * HifiMan Re-400 坏了 * JVC HAF150B == 智能产品 == === 智能手表 === * Moto 360 (Battery dead) * Fossil Gen 5 === 智能灯泡 === * TP-Link KL110 * TP-Link LB130 === 智能插座 === * TP-Link HS100 * Monoprice === 智能家居 === * Google Home Hub * Google Home Mini * Nest Mini == 主机 == === 平板/笔记本 === * Motorola Xoom (dead) * Surface 3 * Surface Pro 4 * Surface Pro 6 * Pixel C (Battery dead) * Pixel Slate * Nexus 7 2013 (Battery dead) * Nexus 7 2012 * Nexus 9 (Sold) * 小新平板 === 台式机 === * goldpeak ** CPU: Intel i7-7700K ** Mem: 4 x 8GB DDR4 ** MB: ASUS PRIME Z270-A [芯片组: Z270] ** NVME: Intel 660p 1TB ** NVME: WD Black SN750 1TB ** HDD: Seagate ST9500325AS 500GB [Seagate Momentus 5400.6, 5400 RPM, 8MB Cache, 2.5'] * brisk ** CPU: Intel i5-2500 ** Mem: 2x 4GB DDR3, 2x 8GB DDR3 ** MB: ASUS P8P67 LE [芯片组:P67] ** NVME: Sandisk Ultra 1TB ** SSD: OCZ Vortex 128GB * dew [Dell Wyse Zx0Q-7020] ** CPU: AMD GX-420CA ** Mem: 2x 4GB DDR3 ** SSD: 32GB * trek [Dell Optiplex 7040] ** CPU: Intel i5-6500T ** Mem: 2x 8GB DDR4 ** SSD: Kingston A400 240GB * nas ** CPU: Intel Pentium G4560 ** Mem: 2x 8GB DDR4 ** MB: ASUS H110I-PLUS ** SSD: HP SSD S700 120GB ** HDD: 3x WD Red WD40EFRX 4TB === 小型设备 === * Pine A64 * Pocket Chip eefb34dc864d763ec996a94c5a5f6c748c028f95 595 594 2020-11-14T05:50:42Z HenryHu 1 /* 显示器 */ wikitext text/x-wiki = My Stuff = == 外设 == === 显示器 === * HP Envy 27 27 寸,IPS 面板,4K 输入:HDMI 1.4, HDMI 1.2,DP,USB-C * Dell U2720Q 27 寸,IPS 面板,4K 输入:HDMI,DP,USB-C * Dell SE2716H 27 寸,VA 面板,2K,曲面 输入:HDMI x 2,VGA * ViewSonic x2 21.5 寸,VA 面板,2K 输入:DVI,VGA === 鼠标 === ==== 有线 ==== * Logitech G500 * Dell Stock Mouse ==== 无线 ==== * Logitech G604 * Logitech G602 * Logitech G700 * Logitech M310 * Logitech M545 * Logitech M570 轨迹球 * Logitech MX Ergo 轨迹球 * Logitech Trackman Marble === 键盘 === ==== 有线 ==== * Filco Majestouch 2 红轴,TenKeyLess * WASD Keyboard V2 青轴,TenKeyLess * DasKeyboard 青轴,全尺寸 * DasKeyboard 全尺寸 * Rosewill RK-9000V2 黑轴,全尺寸 * Dell Stock Keyboard 薄膜键盘,全尺寸 ==== 无线 ==== * Logitech K480 3设备 * Logitech K270 全尺寸 * Microsoft Universal Mobile Keyboard 3设备 * Motorola Wireless Keyboard === 摄像头 === * Microsoft HD3000 * Logitech C922 Pro === 耳机 === ==== 大耳机 ==== * AKG K701 Open * Sennheiser HD598 Open * Sennheiser HD6XX (HD650) Open * Audio Technica ATH-PRO500MK2 Closed * Sony WH1000XM3 主动降噪,蓝牙 * Sennheiser HD201 * BeyerDynamics DT235 * Panasonic RP-HT21 ==== 小耳机 ==== * Shure SE215 半个挂了 * Shure SE425 有线/蓝牙 * Sennheiser HD1 蓝牙 * Sennheiser MX475 * Anker Soundbuds Curve 蓝牙 * Audio Technica ATH-CKM500 坏了 * HifiMan Re-400 坏了 * JVC HAF150B == 智能产品 == === 智能手表 === * Moto 360 (Battery dead) * Fossil Gen 5 === 智能灯泡 === * TP-Link KL110 * TP-Link LB130 === 智能插座 === * TP-Link HS100 * Monoprice === 智能家居 === * Google Home Hub * Google Home Mini * Nest Mini == 主机 == === 平板/笔记本 === * Motorola Xoom (dead) * Surface 3 * Surface Pro 4 * Surface Pro 6 * Pixel C (Battery dead) * Pixel Slate * Nexus 7 2013 (Battery dead) * Nexus 7 2012 * Nexus 9 (Sold) * 小新平板 === 台式机 === * goldpeak ** CPU: Intel i7-7700K ** Mem: 4 x 8GB DDR4 ** MB: ASUS PRIME Z270-A [芯片组: Z270] ** NVME: Intel 660p 1TB ** NVME: WD Black SN750 1TB ** HDD: Seagate ST9500325AS 500GB [Seagate Momentus 5400.6, 5400 RPM, 8MB Cache, 2.5'] * brisk ** CPU: Intel i5-2500 ** Mem: 2x 4GB DDR3, 2x 8GB DDR3 ** MB: ASUS P8P67 LE [芯片组:P67] ** NVME: Sandisk Ultra 1TB ** SSD: OCZ Vortex 128GB * dew [Dell Wyse Zx0Q-7020] ** CPU: AMD GX-420CA ** Mem: 2x 4GB DDR3 ** SSD: 32GB * trek [Dell Optiplex 7040] ** CPU: Intel i5-6500T ** Mem: 2x 8GB DDR4 ** SSD: Kingston A400 240GB * nas ** CPU: Intel Pentium G4560 ** Mem: 2x 8GB DDR4 ** MB: ASUS H110I-PLUS ** SSD: HP SSD S700 120GB ** HDD: 3x WD Red WD40EFRX 4TB === 小型设备 === * Pine A64 * Pocket Chip de3d9b87e354f260bf41155bd927b3b32f7d62bf Messenger Bags 0 175 597 2022-04-09T01:26:10Z HenryHu 1 创建页面,内容为“== Messenger Bags == === Vendors and products === * Chrome ** Citizen ** Buran III ** Mini Metro * Mission Workshop ** Monty ** Monty AP ** Rummy ** Khyte *…” wikitext text/x-wiki == Messenger Bags == === Vendors and products === * Chrome ** Citizen ** Buran III ** Mini Metro * Mission Workshop ** Monty ** Monty AP ** Rummy ** Khyte ** Khyte VX *Timbuk2 ** Classic ** Especial Stash ** Command === Specific Bags === NOPE - too thin: Executive Leather Messenger * Pro: Metal locks * Con: too thin * Leather * Expensive: 419$ NOPE - too wide: Chrome Citizen * Con: large, not for cross body * Con: Plastic Buckles * Con: Too wide - 22' w NOPE - too wide: Chrome Buran III * Con: too wide - 21.5' w * Con: plastic buckle NOPE - not for walking: Timbuk2 Especial Stash * Pro: Metal buckles * Con: bad strap - strap fixed to one side * Pro: lack water bottle storage NOPE - not waterproof: Matt & Nat Vegan Messenger Bag * Con: Vegan * Con: only 13' * Con: not waterproof * Con: lack of pockets NOPE - no longer produced: Timbuk2 Command * Pro: Metal buckle (G-style) * Con: Not crossbody * 5.12' x 17.13' (w) x 14.37' * No longer produced - much more expensive NOPE - too wide: Chrome Mini Metro * Con: not cross body * Con: plastic buckle * Con: Too wide - 20' w NOPE - AP ver: Mission Workshop Monty * Con: Plastic Buckles * Pro: 15' laptop * Con: laptop folder not padded Timbuk2 Classic * Con: Plastic buckle * Pro: crossbody Trakke Bairn Mini Messenger * $200, 10L, 0.9kg * 26 x 35 x 12 cm = 10.2' x 13.8' x 4.7' * Con: only 13' laptop Peak Design Everyday Messenger * $220, 13L, 16' x 11.8' x 6.7' * Con: only 13' Bellroy System Messenger Bag * $199, 16L, 1.05kg * 34 x 46 x 13 cm = 13.4 x 18.1 x 5.1' * Pro: fits 16' laptop * G-hook + magnetic loop Trakke Wee Lug Messenger * $281, 20L, 1.4kg * 30 x 54 x 17 cm / 11.8' x 21.3' x 6.7' * Pro: Metal buckle (G-style) * Con: too wide? Mission Workshop Monty AP * $245, 21L, 1.25kg * Pro: 15' laptop * Con: laptop folder not padded * 16' x 10' x 5' Mission Workshop Khyte * $340 / $395 (VX), 24L, 1.19kg * 21' (w) x 14' (h) x 3.5' * Pro: non-plastic buckle (V-BUCKLE) * Too long? 3e9bd0bf831bea9e1f0146ca888185866d6ab94d Shenzhen I/O 0 176 598 2023-06-19T02:19:34Z HenryHu 1 创建页面,内容为“== Tricks == * Multiple digits can be saved in the same memory cell; each cell can contain 2 or 3 digits. Set a digit with `dst`; get a digit with `dgt`. To eff…” wikitext text/x-wiki == Tricks == * Multiple digits can be saved in the same memory cell; each cell can contain 2 or 3 digits. Set a digit with `dst`; get a digit with `dgt`. To effectively extract the digits, ideally this should be done in a big chip, by putting the data into *dat* and repeatedly move it into *acc*. * Memory chip is also a great accumulator * Memory chip's address port can handle values which are bigger than the max address - it'll wrap around. So you don't need to say `tgt acc 13; +sub 13` * If the range of *acc* is limited, then the extra range can be used to store a bit. Say if the value is 0 ~ 200, then we can `sub 400` from it to use -400 ~ -200 to represent the bit = 1, and the original range to represent bit = 0. 83cd0a14255afb705eacfceb8ec8041698246893 599 598 2023-06-19T02:21:29Z HenryHu 1 /* Tricks */ wikitext text/x-wiki == Tricks == === Memory Chip === * Multiple digits can be saved in the same memory cell; each cell can contain 2 or 3 digits. Set a digit with `dst`; get a digit with `dgt`. To effectively extract the digits, ideally this should be done in a big chip, by putting the data into *dat* and repeatedly move it into *acc*. * Memory chip is also a great accumulator * Memory chip's address port can handle values which are bigger than the max address - it'll wrap around. So you don't need to say `tgt acc 13; +sub 13` === Processor Chip === * If the range of *acc* is limited, then the extra range can be used to store a bit. Say if the value is 0 ~ 200, then we can `sub 400` from it to use -400 ~ -200 to represent the bit = 1, and the original range to represent bit = 0. * An Xbus can be shared by multiple writer; however you should only have 1 reader. * Sometimes `jmp L` can be omitted by carefully placing +/- on the statements below. If you have another test statement, though, this becomes harder. 3ba1940bd928f87488d7d29c798ec2eb73cd56cb 600 599 2023-06-19T02:33:37Z HenryHu 1 /* Processor Chip */ wikitext text/x-wiki == Tricks == === Memory Chip === * Multiple digits can be saved in the same memory cell; each cell can contain 2 or 3 digits. Set a digit with `dst`; get a digit with `dgt`. To effectively extract the digits, ideally this should be done in a big chip, by putting the data into *dat* and repeatedly move it into *acc*. * Memory chip is also a great accumulator * Memory chip's address port can handle values which are bigger than the max address - it'll wrap around. So you don't need to say `tgt acc 13; +sub 13` === Processor Chip === * If the range of *acc* is limited, then the extra range can be used to store a bit. Say if the value is 0 ~ 200, then we can `sub 400` from it to use -400 ~ -200 to represent the bit = 1, and the original range to represent bit = 0. * An Xbus can be shared by multiple writer; however you should only have 1 reader. * Sometimes `jmp L` can be omitted by carefully placing +/- on the statements below. If you have another test statement, though, this becomes harder. The loop statements may be prefixed by loop continuous condition; for example, if we have `teq acc 0; -jmp l`, then we can prefix the statements by '-'. Notice that, however, in the first round, this is decided by the previous comparison, so they may or may not be executed. This can be useful, if you want to skip some statements in the first round, though. 1d97338541a9b432c9a62f843712ac6542fa405a 601 600 2023-06-19T02:34:32Z HenryHu 1 /* Memory Chip */ wikitext text/x-wiki == Tricks == === Memory Chip === * Multiple digits can be saved in the same memory cell; each cell can contain 2 or 3 digits. Set a digit with `dst`; get a digit with `dgt`. To effectively extract the digits, ideally this should be done in a big chip, by putting the data into '''dat''' and repeatedly move it into '''acc'''. * Memory chip is also a great accumulator * Memory chip's address port can handle values which are bigger than the max address - it'll wrap around. So you don't need to say `tgt acc 13; +sub 13` === Processor Chip === * If the range of *acc* is limited, then the extra range can be used to store a bit. Say if the value is 0 ~ 200, then we can `sub 400` from it to use -400 ~ -200 to represent the bit = 1, and the original range to represent bit = 0. * An Xbus can be shared by multiple writer; however you should only have 1 reader. * Sometimes `jmp L` can be omitted by carefully placing +/- on the statements below. If you have another test statement, though, this becomes harder. The loop statements may be prefixed by loop continuous condition; for example, if we have `teq acc 0; -jmp l`, then we can prefix the statements by '-'. Notice that, however, in the first round, this is decided by the previous comparison, so they may or may not be executed. This can be useful, if you want to skip some statements in the first round, though. 651573edf93740d92094f7240cbaf6a73416051a 603 601 2023-06-25T19:29:33Z HenryHu 1 /* Processor Chip */ wikitext text/x-wiki == Tricks == === Memory Chip === * Multiple digits can be saved in the same memory cell; each cell can contain 2 or 3 digits. Set a digit with `dst`; get a digit with `dgt`. To effectively extract the digits, ideally this should be done in a big chip, by putting the data into '''dat''' and repeatedly move it into '''acc'''. * Memory chip is also a great accumulator * Memory chip's address port can handle values which are bigger than the max address - it'll wrap around. So you don't need to say `tgt acc 13; +sub 13` === Processor Chip === * If the range of *acc* is limited, then the extra range can be used to store a bit. Say if the value is 0 ~ 200, then we can `sub 400` from it to use -400 ~ -200 to represent the bit = 1, and the original range to represent bit = 0. * An Xbus can be shared by multiple writer; however you should only have 1 reader. * Sometimes `jmp L` can be omitted by carefully placing +/- on the statements below. If you have another test statement, though, this becomes harder. The loop statements may be prefixed by loop continuous condition; for example, if we have `teq acc 0; -jmp l`, then we can prefix the statements by '-'. Notice that, however, in the first round, this is decided by the previous comparison, so they may or may not be executed. This can be useful, if you want to skip some statements in the first round, though. * Use 'dst 2 0' to get the absolute value. 0c3ebc96f6566bf4db1dc15ba164d2c8f8e8032a Home Improvement Plan 0 177 604 2023-07-16T17:12:53Z HenryHu 1 Start of Home Improvement Project wikitext text/x-wiki == Home Improvement Plan == Documents improvements to the home environment. === July 15, 2023 === * Thrown the garbage out (Agatha) === July 16, 2023 === * Folded the clothes (Together) * Opened doors and windows for fresh air (Henry) 4884bef61d6d9bbf00728f15ac2117f54d0fbdd6 Restaurants 0 178 606 2023-07-23T03:07:04Z HenryHu 1 创建页面,内容为“== Restaurants == === Long Island City === * 琥珀 四川 - 评价:差 ** 有点心和川菜 ** 贵,量少 ** 奶茶过甜,贵,糖精多,不好喝” wikitext text/x-wiki == Restaurants == === Long Island City === * 琥珀 四川 - 评价:差 ** 有点心和川菜 ** 贵,量少 ** 奶茶过甜,贵,糖精多,不好喝 ec85ce92304771126c3e53468897378ced70fa06 KDE 0 179 608 2023-12-01T19:46:40Z Nuk 25 创建页面,内容为“= KDE Tricks = == Check if user service are normal == Command: <code> systemctl --user status </code> If it shows "degraded", some services are not running or sta…” wikitext text/x-wiki = KDE Tricks = == Check if user service are normal == Command: <code> systemctl --user status </code> If it shows "degraded", some services are not running or started properly. You could use "systemctl --user |grep failed" to list all the failed services. de1bd48305df07bf6cb5d132c34ccb37039bd5e3 609 608 2023-12-01T19:47:03Z Nuk 25 wikitext text/x-wiki = Check if user services are normally started = Command: <code> systemctl --user status </code> If it shows "degraded", some services are not running or started properly. You could use "systemctl --user |grep failed" to list all the failed services. 04fb626ec8d9cd48d425122791821d73cf29ebba OpenSUSE 0 132 610 524 2023-12-01T19:47:26Z Nuk 25 wikitext text/x-wiki 列一下openSUSE系统管理常见的命令 [[KDE]] [[magit]] [[Suse_grub]] [[OBS]] [[Suse_systemd]] [[Suse_nvidia]] [[pdftotext]] = RPM = == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 查询一个package的dependency == * rpm -qR $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 添加一个源 == * zypper ar -f $URL $ALIAS == zypper删除一个Application == * zypper rm -t Application $APP_NAME zypper rm application:$APP_NAME 如果这样删不掉的话,这个命令可以告诉我们这个Application中包含哪些package。 我们需要先删除这个Application中包含的package,然后再删除这个application。 == 显示所有找不到源的包 == * zypper pkg --orphan 得到的结果不全 * zypper se -i |grep "System Packages" 这样应该是全的 * zypper pkg --unneeded 显示所有没有任何dependency的包(不被其他任何包依赖)。 == zypper中Application的xml文件位置(以Dolphin为例) == /usr/share/appdata/dolphin.appdata.xml = Ghostscript = == 去pdf密码 == gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=unencrypted.pdf -c .setpdfwrite -f encrypted.pdf 63a9c4e8cdeacaeb0580a5aef1811bbda32b473c Suse systemd 0 135 611 494 2023-12-02T13:44:28Z Nuk 25 /* 用户个人服务 */ wikitext text/x-wiki = 用户个人服务 = * Unit位置 ~/.config/systemd/user/ * 开机自动启动服务 systemctl --user enable XXX.service * 清除failed服务 systemctl --user reset-failed * 更新服务文件后重新载入 systemctl --user daemon-reload * 查看服务状态 systemctl --user status XXX.service = unit路径 = * 软件包的unit路径 /usr/lib/systemd/system /usr/lib/systemd/user * Administrator的unit路径 /etc/systemd/system /etc/systemd/user * 用户个人的unit路径 $HOME/.config/systemd/user/ c6d3296be127b310ae485a08483afee6ea600842 Fcitx5 0 180 612 2023-12-10T23:30:28Z Nuk 25 创建页面,内容为“= Fcitx5 on openSUSE = Fcitx5在openSUSE上面的打包在KDE+Wayland上运行有如下问题: 1. 根据Fcitx官网上的Wayland Best Practice (https://fcitx-i…” wikitext text/x-wiki = Fcitx5 on openSUSE = Fcitx5在openSUSE上面的打包在KDE+Wayland上运行有如下问题: 1. 根据Fcitx官网上的Wayland Best Practice (https://fcitx-im.org/wiki/Using_Fcitx_5_on_Wayland) 需要将KDE System Settings里面设置Virtual Keyboard为fcitx5。这一设置会使得KDE在启动时自动启动fcitx5。这个设定会与fcitx5打包中的/etc/xdg/autostart/org.fcitx.Fcitx5.desktop以及/usr/lib/systemd/user/fcitx5.service发生冲突,导致后两者启动失败。 目前的解决方案是将上述.service和.desktop文件删除。 2. 同样根据上述Wayland Best Practice,将Virtual Keyboard设置为fcitx5之后,无需再设置QT_IM_MODULE以及GTK_IM_MODULE等环境变量。但是目前Tumbleweed的打包会将上面两个环境变量通过/usr/etc/X11/xim.d/fcitx5以及同目录下其他一系列文件进行设置。目前的解决方案是删除/usr/etc/X11/xim.d/目录下面所有包含fcitx的文件。 c794ebd9fba9c2ba4f90f666c1c1513be0e338ad 613 612 2023-12-10T23:32:02Z Nuk 25 wikitext text/x-wiki = Fcitx5 on openSUSE = Fcitx5在openSUSE上面的打包在KDE+Wayland上运行有如下问题: 1. 根据Fcitx官网上的 [https://fcitx-im.org/wiki/Using_Fcitx_5_on_Wayland Wayland Best Practice],实现最佳效果需要将KDE System Settings里面设置Virtual Keyboard为fcitx5。这一设置会使得KDE在启动时自动启动fcitx5。这个设定会与fcitx5打包中的/etc/xdg/autostart/org.fcitx.Fcitx5.desktop以及/usr/lib/systemd/user/fcitx5.service发生冲突,导致后两者启动失败。 目前的解决方案是将上述.service和.desktop文件删除。 2. 同样根据上述[https://fcitx-im.org/wiki/Using_Fcitx_5_on_Wayland Wayland Best Practice],将Virtual Keyboard设置为fcitx5之后,无需再设置QT_IM_MODULE以及GTK_IM_MODULE等环境变量。但是目前Tumbleweed的打包会将上面两个环境变量通过/usr/etc/X11/xim.d/fcitx5以及同目录下其他一系列文件进行设置。目前的解决方案是删除/usr/etc/X11/xim.d/目录下面所有包含fcitx的文件。 9f9d421f526bede7495829e20cfa980cd3aa7f3e Cold Medicine 0 181 614 2024-01-15T21:36:31Z HenryHu 1 创建页面,内容为“== 感冒药 == 止咳/cough suppresant: * Dextromethorphan (DXM) / 右美沙芬 鼻通气/nasal decongestant: * Phenylephrine / Sudafed PE / 苯福林 -> 口服…” wikitext text/x-wiki == 感冒药 == 止咳/cough suppresant: * Dextromethorphan (DXM) / 右美沙芬 鼻通气/nasal decongestant: * Phenylephrine / Sudafed PE / 苯福林 -> 口服无效! * Pseudoephedrine / Sudafed / 伪麻黄碱 止痛/降温: * acetaminophen / 扑热息痛 对乙酰氨基酚 - COX-2 * aspirin / 阿司匹林 - COX-1 止痛: * Ibuprofen / Advil / 布洛芬 7cc6aaae4ef1d9f28792b137d05fc4be2ce55fe1 Epson 0 182 615 2024-11-18T15:26:23Z Nuk 25 创建页面,内容为“= Epson ET-2760 Scanner Linux Setup = == 打印机 == 安装 == 扫描仪 == 1. 启用SANE的ESCL后端: <pre> $ sudo zypper in sane-backends $ sudo vim /etc…” wikitext text/x-wiki = Epson ET-2760 Scanner Linux Setup = == 打印机 == 安装 == 扫描仪 == 1. 启用SANE的ESCL后端: <pre> $ sudo zypper in sane-backends $ sudo vim /etc/sane.d/dll.conf # dll.conf: Uncomment to enable the escl backend # escl escl </pre> 2. 配置ESCL后端: <pre> $ sudo vim /etc/sane.d/escl.conf # escl.conf: Add the following line device http://192.168.XX.YY:443 "Epson ET-2760" </pre> 测试: <pre> $ scanimage -L or $ skanlite </pre> 53b5932c111c34fbd7b1cb4cdf517d7b3b0891a8 Epson 0 182 616 615 2024-11-18T15:26:54Z Nuk 25 wikitext text/x-wiki = Epson ET-2760 Scanner Linux Setup = == 打印机 == 安装 == 扫描仪 (通过Wi-fi 连接) == 1. 启用SANE的ESCL后端: <pre> $ sudo zypper in sane-backends $ sudo vim /etc/sane.d/dll.conf # dll.conf: Uncomment to enable the escl backend # escl escl </pre> 2. 配置ESCL后端: <pre> $ sudo vim /etc/sane.d/escl.conf # escl.conf: Add the following line device http://192.168.XX.YY:443 "Epson ET-2760" </pre> 3. 连接测试: <pre> $ scanimage -L or $ skanlite </pre> f93d3c6bbe39a3071fd81bf0976c2a72a8d3a4dc 617 616 2024-11-18T15:28:29Z Nuk 25 /* 打印机 */ wikitext text/x-wiki = Epson ET-2760 Scanner Linux Setup = == 打印机 == 安装驱动 <pre> sudo zypper in epson-inkjet-printer-escpr </pre> == 扫描仪 (通过Wi-fi 连接) == 1. 启用SANE的ESCL后端: <pre> $ sudo zypper in sane-backends $ sudo vim /etc/sane.d/dll.conf # dll.conf: Uncomment to enable the escl backend # escl escl </pre> 2. 配置ESCL后端: <pre> $ sudo vim /etc/sane.d/escl.conf # escl.conf: Add the following line device http://192.168.XX.YY:443 "Epson ET-2760" </pre> 3. 连接测试: <pre> $ scanimage -L or $ skanlite </pre> 35ec7f24cb57999333e4f7e613298b0e7afead76 618 617 2024-11-18T15:28:43Z Nuk 25 wikitext text/x-wiki = Epson ET-2760 Scanner Linux Setup = == 打印机 == 安装驱动即可: <pre> sudo zypper in epson-inkjet-printer-escpr </pre> == 扫描仪 (通过Wi-fi 连接) == 1. 启用SANE的ESCL后端: <pre> $ sudo zypper in sane-backends $ sudo vim /etc/sane.d/dll.conf # dll.conf: Uncomment to enable the escl backend # escl escl </pre> 2. 配置ESCL后端: <pre> $ sudo vim /etc/sane.d/escl.conf # escl.conf: Add the following line device http://192.168.XX.YY:443 "Epson ET-2760" </pre> 3. 连接测试: <pre> $ scanimage -L or $ skanlite </pre> 750b14cb0eed3a3a8eaa845ee41b7509e642b489 OpenSUSE 0 132 619 610 2025-01-03T19:52:04Z Nuk 25 /* RPM */ wikitext text/x-wiki 列一下openSUSE系统管理常见的命令 [[KDE]] [[magit]] [[Suse_grub]] [[OBS]] [[Suse_systemd]] [[Suse_nvidia]] [[pdftotext]] = RPM = == Macros == === %setup === -q: quiet mode -T: disable unpacking the first source tarball -D: disable deleting the first source directory -n: specify the name of the tarball and its directory -b <n>: unpack %{S:n} before entering the first source directory == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 查询一个package的dependency == * rpm -qR $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 添加一个源 == * zypper ar -f $URL $ALIAS == zypper删除一个Application == * zypper rm -t Application $APP_NAME zypper rm application:$APP_NAME 如果这样删不掉的话,这个命令可以告诉我们这个Application中包含哪些package。 我们需要先删除这个Application中包含的package,然后再删除这个application。 == 显示所有找不到源的包 == * zypper pkg --orphan 得到的结果不全 * zypper se -i |grep "System Packages" 这样应该是全的 * zypper pkg --unneeded 显示所有没有任何dependency的包(不被其他任何包依赖)。 == zypper中Application的xml文件位置(以Dolphin为例) == /usr/share/appdata/dolphin.appdata.xml = Ghostscript = == 去pdf密码 == gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=unencrypted.pdf -c .setpdfwrite -f encrypted.pdf 2d9b3b23d99d9eeab533116750265e2cc9612d0f 620 619 2025-01-03T19:52:30Z Nuk 25 wikitext text/x-wiki 列一下openSUSE系统管理常见的命令 [[KDE]] [[magit]] [[Suse_grub]] [[OBS]] [[Suse_systemd]] [[Suse_nvidia]] [[pdftotext]] = RPM = == Macros == === %setup === -q: quiet mode -T: disable unpacking the first source tarball -D: disable deleting the first source directory -n: specify the name of the tarball and its directory -b <n>: unpack %{S:n} before entering the first source directory -a <n>: unpack %{S:n} after entering the first source directory == 列出一个package的文件列表 == * rpm -ql $PACKAGE_NAME == 查询一个package的dependency == * rpm -qR $PACKAGE_NAME == 给一个文件(夹),查询它属于哪个package == * rpm -qf $FILE_NAME = Zypper = == 添加一个源 == * zypper ar -f $URL $ALIAS == zypper删除一个Application == * zypper rm -t Application $APP_NAME zypper rm application:$APP_NAME 如果这样删不掉的话,这个命令可以告诉我们这个Application中包含哪些package。 我们需要先删除这个Application中包含的package,然后再删除这个application。 == 显示所有找不到源的包 == * zypper pkg --orphan 得到的结果不全 * zypper se -i |grep "System Packages" 这样应该是全的 * zypper pkg --unneeded 显示所有没有任何dependency的包(不被其他任何包依赖)。 == zypper中Application的xml文件位置(以Dolphin为例) == /usr/share/appdata/dolphin.appdata.xml = Ghostscript = == 去pdf密码 == gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=unencrypted.pdf -c .setpdfwrite -f encrypted.pdf c0009632e38dc693527cac750f43c216e5ec0a6b 621 620 2025-01-03T19:58:21Z Nuk 25 wikitext text/x-wiki 列一下openSUSE系统管理常见的命令 [[KDE]] [[magit]] [[Suse_grub]] [[OBS]] [[Suse_systemd]] [[Suse_nvidia]] [[pdftotext]] = RPM = == Macros == === %setup === -q: quiet mode -T: disable unpacking the first source tarball -D: disable deleting the first source directory -n: specify the name of the tarball and its directory -b <n>: unpack %{S:n} before entering the first source directory -a <n>: unpack %{S:n} after entering the first source directory == Command Line Options == === 列出一个package的文件列表 === * rpm -ql $PACKAGE_NAME === 查询一个package的dependency === * rpm -qR $PACKAGE_NAME === 给一个文件(夹),查询它属于哪个package === * rpm -qf $FILE_NAME = Zypper = == Command Line Options == === 添加一个源 === * zypper ar -f $URL $ALIAS === zypper删除一个Application === * zypper rm -t Application $APP_NAME zypper rm application:$APP_NAME 如果这样删不掉的话,这个命令可以告诉我们这个Application中包含哪些package。 我们需要先删除这个Application中包含的package,然后再删除这个application。 === 显示所有找不到源的包 === * zypper pkg --orphan 得到的结果不全 * zypper se -i |grep "System Packages" 这样应该是全的 * zypper pkg --unneeded 显示所有没有任何dependency的包(不被其他任何包依赖)。 === zypper中Application的xml文件位置(以Dolphin为例) === /usr/share/appdata/dolphin.appdata.xml = Ghostscript = == 去pdf密码 == gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=unencrypted.pdf -c .setpdfwrite -f encrypted.pdf 8390a69198a15267b66af3c4af0379dec991f9c9 OBS 0 133 622 506 2025-01-13T15:49:57Z Nuk 25 wikitext text/x-wiki 本页保存一些Open Build System使用记录。 = OBS RPM Lint = == W:unstripped-binary-or-object == == W:no-soname == There is no DT_SONAME field defined in the so file. = RPM 宏定义查询 = * RPM Macros - /usr/lib/rpm/macros * RPM KDE4 Macros - /etc/macros/macros.kde4 = osc 常用命令 = * 修改project的build target - osc meta prj -e home:nuklly * 修改project中某个package的metadata - osc meta pkg -e home:nuklly hplip * 删除project中的一个package - osc rdelete <package> a590fb6da015d781223a633581c93b2ce4b53688